巨大なCSVでMemoryErrorになる

Prep

巨大なCSVでMemoryErrorになる

作成日: 最終更新: 読了時間: 1 分

数 GB 以上の CSV を read_csv() で読み込むと、途中で

MemoryError: Unable to allocate XX GiB for an array with shape (…)

と表示されて処理が止まることがあります。
ローカル PC で扱うにはメモリが足りないため、分割して読む・不要な列を捨てる・型を最適化する といった工夫が必要です。


解決法 1: チャンク単位で読み込む #

import pandas as pd

chunks = pd.read_csv("big.csv", chunksize=100_000)
total = 0
for chunk in chunks:
    total += chunk["amount"].sum()

print(total)

chunksize= を指定するとイテレータが返り、複数回に分けてメモリに載せられる ようになります。
並列処理する場合は dask.dataframepolars の利用も検討してください。


解決法 2: 必要な列だけ読み込む #

use_columns = ["customer_id", "amount", "created_at"]
df = pd.read_csv("big.csv", usecols=use_columns)

usecols= で列を絞れば、読み込み時点で無駄な領域を確保せずに済みます。
分析に不要な列は最初から捨ててしまいましょう。


解決法 3: dtype を先に指定する #

dtypes = {
    "customer_id": "int32",
    "amount": "float32",
    "is_active": "boolean",
}

df = pd.read_csv("big.csv", dtype=dtypes, memory_map=True)

デフォルトでは推定結果が float64object になるため無駄なメモリを消費します。
int32float32、カテゴリー列なら category 型を指定して削減しましょう。
memory_map=True を付けるとファイルをメモリマップして効率的にアクセスできます。


解決法 4: 圧縮ファイルのまま読み込む #

df = pd.read_csv("big.csv.gz", compression="gzip")

gzip や zip など、圧縮された状態でも pandas はそのまま読み込めます。
ネットワーク越しにダウンロードする場合は、圧縮ファイルを解凍せず compression= を指定するのが安全です。


チェックリスト #

  1. 本当に全列を読む必要があるか (usecols)
  2. 数値・分類列の 型ダウンキャスト を行ったか
  3. チャンク処理や分割保存など、段階的処理 に切り替えられないか
  4. メモリに載せずに済む dask, polars, DuckDB など他ツールの活用も検討したか

参考 #