🐣

とりあえず、コレ覚えとけ、pandas入門

に公開

0. はじめに

  • (一応)現役データサイエンティストである筆者が、業務でよく使うメソッドを元に、どんな順番で学んだらよいかを順番に解説してみた
  • pythonのライブラリは、"マニュアルは完全読破!"よりも"使ってなれるハンズオン形式+必要になったら調べる"で身につけたほうが良いと思うため、こんな形式にしている
  • てか、最近は公式リファレンスも説明の質があがっているため、ただの解説記事だと劣化になりかねない…ので! 便利なメソッドよりも、最低限戦えるメソッド等を紹介することにしました。

想定する読者

  • pythonの基礎はわかる(python3エンジニア認定基礎以上の知識がある)
  • pandasのメソッドは知っているが、どう活用するかイメージが湧かない

PC環境等

  • OS:Windows11 Home
  • python : 3.13.5
    • pandas : 2.3.3
    • numpy : 2.3.5

ちなみに

pandasの公式チュートリアルが分かりやすいので、「DataFrameとは何ぞや?」などの疑問はこちらを参照ください。
素人が書いた記事よりも、公式ドキュメントのほうが1次情報だし有用だと思います。
https://pandas.dokyumento.jp/docs/getting_started/index.html#getting-started

1. よく使うクラス・関数・メソッド

ここからは個人的によく使う関数を順番に解説していくよー

1.1 pd.DataFrame

  • pandasの核となるDataFrame作成する

list in dictの場合

  • dictのkeyが列名となる
  • 列ごとに数値を計算してからDataFrameに追加する場合などはこの方式が便利
list_in_dict = {"A": [1, 2, 3],
                "B": [4, 5, 6]}
df = pd.DataFrame(list_in_dict)
print("=== list_in_dict ===\n", df)

他にもlist in listやdict in listなどで挙動が変わるため、詳しく知りたい方は下記折り畳みを参照のこと

引数による違いについて

引数によっていろいろ挙動が異なるため、まとめておく

list_in_list

  • 外のlistの要素が行として、中のlistの要素が列として扱われる
  • 列名と行名をpd.DataFrameの引数で定義するため、list in listの各値の意味が見づらい
list_in_list = [[1, 4],
                [2, 5],
                [3, 6]]
df = pd.DataFrame(list_in_list, columns=["A", "B"])
print("=== list_in_list ===\n", df)

dict in list

  • listの中にdictを入れると、dictのKeyが列名として扱われる
  • 返値がdictである他の関数・メソッド等を、1つのcsvにまとめたい際に便利
dict_in_list = [{"A": 1, "B": 4},
                {"A": 2, "B": 5},
                {"A": 3, "B": 6}]
df = pd.DataFrame(dict_in_list)
print("=== dict_in_list ===\n", df)

dict in dict

  • 外のdictのKeyが列、中のdictのKeyが行として扱われる
  • dict in dictの時点で完全に要素の意味が保持できている一方、行数が増えるとdictのKeyが無駄に多くなりがち
dict_in_dict = {"A": {"X": 1, "Y": 2, "Z": 3},
                "B": {"X": 4, "Y": 5, "Z": 6}}
df = pd.DataFrame(dict_in_dict)
print("=== dict_in_dict ===\n", df)

from np.array

  • np.arrayの2次元の場合はそのままDataFrameへ変換可能
  • numpyの乱数生成等を組み合わせたり、巨大な配列を元にDataFrameを作成したい際によく使う
  • DataFrame内の値の型は、numpy内の値の型を基本的に引き継ぎます(一部例外あり)
import numpy as np
np_2darray = np.zeros((5000, 2), dtype="float16")
df = pd.DataFrame(np_2darray, columns=["A", "B"])
print("=== np.array ===\n", df)

よっぽどnumpyを使った方が高速で可読性が高いです

  • numpyライブラリを使用してもよい → numpy.zerosやonesで配列作成
  • numpyライブラリをどうしてもimportしたくない(使いたくない) → list内包表記で作成

1.2 to_csv()

  • DataFrameをcsvファイルとして保存する
  • 引数によって、文字コードの指定、区切り文字の指定、一部の列名のみ書き出し 等が可能
df.to_csv('./dataframe.csv', encoding="shift-jis")
引数 内容
sep ",", "\t" ファイル出力時の区切り文字を指定する(\tはTabに相当)
encoding "shift-jis", "utf-8"等 文字コードの指定
columns 列名のリスト 一部の列のみを抽出して保存したい場合に指定

公式リファレンス

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_csv.html

1.3 pd.read_csv()

  • csvファイルをDataFrameとして読み込む
  • 引数によって、文字コードの指定や型の指定、先頭〇行を飛ばして読み込む 等の調整が可能
  • parse_datesやindex_colはここで指定しておくと、無駄にpd.to_datetimeやdf.indexを使うコードを削減できる
df = pd.read_csv('dataframe.csv', encoding="shift-jis", index_col=0)

よく使う引数はこのあたり

引数 内容
sep ",", "\t" ファイルを読み込み際の区切り文字を指定する(\tはTabに相当)
index_col 0, Falseなど indexとして使用する列番号を指定する
encoding "shift-jis", "utf-8"等 文字コードの指定
dtype {'a': np.float64, 'b': np.int32}等 列ごとに型を指定して読み込む
parse_dates True, 列名のlistなど datetime型として読み込む列名を指定する(Trueの場合、indexをdatetime型として読み込む)
skiprows 3などint型の整数など ファイル先頭行のN番目までを読み飛ばす(既製品のなんちゃってcsvを読み込む際に便利)

公式リファレンス

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_csv.html

1.4 データの一部の抽出(at, loc, iat, iloc)

  • 列名・行名を指定して1つの要素を抽出する場合はat
  • 複数該当するものを抽出する場合はlocを使う

行名・列名で参照する(at, loc)

print("=== 列名・行名で参照(at, loc) ===")
print(df.at[1, "A"])
print(df.loc[:, "A"])  # 列名がAの列を参照
print(df.loc[1, :])  # 行名が1の行を参照

行番号・列番号で参照する(iat, iloc)

  • at, locのindex参照版
  • プログラム的にはfor文を回して参照する際にはこちらの方が便利
# indexで参照
print("=== indexで参照(iat, iloc) ===")
print(df.iat[1, 0])
print(df.iloc[:, 0])  # 列名がAの列を参照
print(df.iloc[1, :])  # 行名が1の行を参照

1.5 index, columns, valuesの取得

  • DataFrameの各値を取得する
  • index, columnsの返値はlistではないため注意
  • 値のmatrixを取得する方法として、df.valuesもあるが、公式では非推奨[1]
print(df.columns, type(df.columns))  # 列名(<class 'pandas.core.indexes.base.Index'>)
print(df.index, type(df.index))  # 行名(<class 'pandas.core.indexes.base.Index'>)
print(df.to_numpy())  # nd_arrayに変換

print(df.to_dict())  # dict in dictに変換

1.6 並び変える(sort_values)

  • 列の要素ごとに昇順・降順に並び替えるメソッド
  • byやascendingはlist型で指定することで、複数列を昇順・降順を指定してソートすることができる
df = pd.DataFrame({"A": [1, 100, 10], "B": [4, 5, 6]})
print(df.sort_values(by="A"))  # 昇順ソート
print(df.sort_values(by="B", ascending=False))  # 降順ソート

公式ドキュメント

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.sort_values.html

1.7 条件抽出(query)

  • 列の要素ごとに条件に当てはまる行を抽出するメソッド
  • SQLに似た使いかたができるが、記法にクセがあり使いこなすまでエラーが多発するかも
df = pd.DataFrame({"value": range(0, 7), "alphabet": list("ABCDEFG")})
print(df)
print(df.query(' value%2 == 0'))
print(df.query(' alphabet in ["A", "C", "F"] and value%2 == 0'))

公式リファレンス

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.query.html

1.8 DataFrame同士の結合(pd.concat / pd.merge)

  • 単純に結合する場合はpd.concatを用いる
  • ある列の要素が同じDataFrame同士を行方向に結合したい場合はmergeを用いる
df_A = pd.DataFrame({"A": range(0, 7), "B": list("ABCDEFG")})
df_C = pd.DataFrame({"A": range(0, 3), "C": list("XYZ")})
print("=== concat ===\n", pd.concat([df_A, df_C], axis=0))
print("=== merge ===\n", pd.merge(df_A, df_C, how="inner"))

1.9 重複削除(drop_duplicates)

  • subsetで指定した列の値が重複している場合、1つを残して除くメソッド
  • subsetにはlistで複数列名を指定可能
  • keepはどの要素を残すか選択できる("first", "last"など)
df_A = pd.DataFrame({"A": range(0, 7), "category": list("AABBCCD")})
print(df_A)
print(df_A.drop_duplicates(subset=["category"], 
                           keep="first", 
                           ignore_index=True))

1.10 ユニーク配列の取得(unique)

  • 列ごとに値によって処理を分けたい場合に便利
  • 返値はnp.ndarrayなので注意(listやtupleではない)
df_A = pd.DataFrame({"A": range(0, 7), "category": list("AABBCCD")})
print(df_A)
for category in df_A["category"].unique():
    print(f"=== {category=} ===")
    print(df_A.query(f'category == "{category}"'))
print(type(df_A["category"].unique()))  # <class 'numpy.ndarray'>

1.11 各種集計関数

  • 基本的な集計関数(sum, mean, std, median, quantileなど)は計算可能
  • count()はNoneやnan等を除いた件数を算出するため、不値の確認等に使える
df_A = pd.DataFrame({"A": range(0, 7), "B": [1, 2, 3, 4, 5, 6, None]})

print("=== df_A.sum() ===\n", df_A.sum(), "\n")
print("=== df_A.mean() ===\n", df_A.mean(), "\n")
print("=== df_A.std() ===\n", df_A.std(), "\n")
print("=== df_A.median() ===\n", df_A.median(), "\n")
print("=== df_A.quantile() ===\n", df_A.quantile(q=0.75), "\n")
print("=== df_A.count() ===\n", df_A.count())

ちなみに、特定の列の集計飲みしたい場合は、以下のように.locと併用すればよい

print('=== df_A.loc[:, "A"].sum() ===\n', df_A.loc[:, "A"].sum())

2. まとめ

  • pandasのよく使う機能についてまとめた
  • pythonのライブラリは機能が多く、公式のAPI referenceはどれから手を付けたら良いかわかりづらくなってきている
  • もしpandasを新しく学ぶ人が、本記事で紹介した順番に学んでくれたらちょっぴりうれしいかも

参考

[1] : "Warning We recommend using DataFrame.to_numpy() instead." と記載がある
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.values.html

Discussion