Pandasはデータ分析に非常に便利ですが、大規模データや複雑な処理になると「遅い」と感じることがあります。
ここでは、Pandasを高速化するためのテクニックを体系的に解説します。
大きく分けると「処理方法の工夫」「データ型の最適化」「外部ライブラリの活用」の3つの観点があります。
目次
処理方法の工夫
ループを避ける(ベクトル化)
for
ループやapply
を多用すると遅くなります。- 代わりにPandasやNumPyが持つベクトル化演算を使うとCレベルで処理され高速化されます。
import pandas as pd
import numpy as np
# サンプルデータ
df = pd.DataFrame({"col": np.arange(1, 6)})
# 遅い方法(apply)
df["new_apply"] = df["col"].apply(lambda x: x + 1)
# 速い方法(ベクトル化)
df["new_vectorized"] = df["col"] + 1
print(df)
条件分岐はnp.where
やmask
を使う
# 遅い方法(apply)
df["flag_apply"] = df.apply(lambda x: 1 if x["col"] > 3 else 0, axis=1)
# 速い方法(np.where)
df["flag_where"] = np.where(df["col"] > 3, 1, 0)
print(df)
文字列操作は専用メソッドを活用
- Pythonの標準文字列処理より、Pandasの
.str
アクセサの方が高速。
df_str = pd.DataFrame({"text": [" Hello ", " World ", " Python "]})
# 文字列操作(高速)
df_str["cleaned"] = df_str["text"].str.lower().str.strip()
print(df_str)
GroupBy・集計の効率化
- 不要な列は事前に削除してから集計する。
groupby().agg()
で複数の統計量を一度に計算すると効率的。
データ型の最適化
astype
で型を縮小
- int64 → int32
- float64 → float32
- object → category
df_dtype = pd.DataFrame({
"id": [1, 2, 3, 4],
"category_col": ["A", "B", "A", "C"]
})
# メモリ削減のため型変換
df_dtype["id"] = df_dtype["id"].astype("int32")
df_dtype["category_col"] = df_dtype["category_col"].astype("category")
print(df_dtype.dtypes)
これによりメモリ使用量が大幅削減 → 計算も高速化。
入出力の高速化
CSVよりParquetやFeatherを使う
- CSVはテキスト形式なのでI/Oが遅い。
- ParquetやFeatherはバイナリ形式で高速。
# サンプルデータ
df_io = pd.DataFrame({"col1": range(1000), "col2": range(1000, 2000)})
# Parquet形式で保存
df_io.to_parquet("data.parquet")
# 読み込み
df_parquet = pd.read_parquet("data.parquet")
print(df_parquet.head())
その他のテクニック
- 列アクセスは
.loc
や.iloc
を使う(辞書的アクセスより速い)。 - 必要な列だけ読み込む(
usecols
を指定)。 - sort_valuesは必要な時だけ実行。
- 不要なインデックス操作を避ける。
まとめ
- まずベクトル化・型変換・I/O最適化で80%以上の速度改善が可能。
- さらに大規模データではDaskやModinを検討。
- メモリ削減と並列処理が鍵。
以上、PythonのPandasを高速化する方法についてでした。
最後までお読みいただき、ありがとうございました。