CSV全体を一度に読み込めない場合は、分けて読みながら集計値を積み上げることができます。pandasのread_csvにchunksizeを指定すると、指定した件数ごとに表を受け取れます。
ただし、分割した表を全部リストへためてから結合すれば、全体を保持する量は再び増えます。部門別の合計なら、各部分の合計と件数だけを残す形にできます。平均も最後に合計を件数で割って求めます。
小さなCSVを二件ずつ読む
次は五件の架空CSVです。練習では二件ずつ読みます。実ファイルならStringIO(text)を入力パスへ置き換え、chunksizeはその環境で扱える量を確かめて決めてください。
from collections import defaultdict
from io import StringIO
import pandas as pd
text = "部門,金額\nA,10\nA,20\nB,30\nA,40\nB,50\n"
totals = defaultdict(int)
counts = defaultdict(int)
with pd.read_csv(
StringIO(text),
dtype={"部門": "string", "金額": "int64"},
chunksize=2,
) as reader:
for chunk in reader:
if chunk["部門"].isna().any() or chunk["部門"].eq("").any():
raise ValueError("部門を確認してください")
grouped = chunk.groupby("部門")["金額"].agg(["sum", "count"])
for department, row in grouped.iterrows():
totals[department] += int(row["sum"])
counts[department] += int(row["count"])
if not counts:
raise ValueError("データ行がありません")
for department in sorted(totals):
print(f"{department} 合計={totals[department]} 件数={counts[department]} 平均={totals[department] / counts[department]:.2f}")
assert dict(totals) == {"A": 70, "B": 80}
assert sum(totals.values()) == pd.read_csv(StringIO(text))["金額"].sum()
Aは合計70・三件・平均23.33、Bは合計80・二件・平均40.00です。最後の一括読み込みはこの小さな練習データで結果を照合するためのものです。大きな実ファイルの本処理へ、そのまま検算用の全件読込を入れる必要はありません。
Windows・Python 3.12.10・pandas 3.0.2で掲載例を実行しました。大容量ファイルの処理時間やメモリー使用量を測った例ではありません。
部分平均を平均しない
チャンクごとの平均を足してチャンク数で割ると、各チャンクの件数が違う場合に全体の平均になりません。最後のチャンクだけ件数が少ない場合や、部門ごとの件数に偏りがある場合も同じです。
合計と件数を累積すれば、その比で全体の平均を出せます。金額に欠損を認める場合は、平均の分母を全行数にするのか有効な値の件数にするのかも決めてください。この例は整数型で読み、不正な数値や未入力をそのまま通しません。
全体を見ないと決まらない処理
合計は部分ごとに足せますが、中央値や全体の順位、別チャンクをまたぐ重複の検出は、同じ数行を足すだけでは済みません。今回のコードを、すべての集計の置き換えには使いません。
列型を明示しないと、前半は数値、後半は文字が混ざるといった入力で、チャンクごとの解釈が変わることもあります。形式が違う部分を黙って読み飛ばさず、対象ファイルと処理した範囲が分かる形で止めます。
検算には既知の合計を持つ小さな入力を使います。一件だけ、指定件数ちょうど、最後の部分が余る件数などを試し、入力を全部読めたことと、集計値の一致を分けて確認してください。
基本の集計はCSVの合計・平均を出す方法、列型の扱いはpandas入門で補えます。
参考資料
pandas.read_csvとgroupbyの公式資料を2026年11月1日に確認しました。
