サイズ大CSVを、chunkサイズで読み込む

投稿者: | 2021-11-27

目次

手法1

  • read_csv に chunksize オプションを指定することでファイルの中身を 指定した行数で分割して読み込むことができる。chunksize には 1回で読み取りたい行数を指定する。例えば 50 行ずつ読み取るなら、chunksize=50
  • chunksize を指定したとき、返り値は DataFrame ではなく TextFileReader インスタンスとなる。
  • TextFileReader を for でループさせると、ファイルの中身を指定した行数ごとに DataFrame として読み取る。TextFileReader は 現時点での読み取り位置 (ポインタ) を覚えており、ファイルの中身をすべて読み取るとループが終了する。
%%time
# chunksize指定で読み込んだ場合、DFではなく、TextFileReader(インスタンス)になる
reader = pd.read_csv(big_p, chunksize=1000000)

# それをconcatして結合する
df = pd.concat((r for r in reader), ignore_index=True)

手法2

  • データ加工/可視化 100本ノック本より
df = pd.read_csv(big_data)

# もしデータが100万〜数1000万行以上のデータだと、一気に読み込むとOOMエラー(メモリ不足)でプログラムが終了してしまう
# それを回避するため、chunksizeを指定

for df in pd.read_csv(big_data, chunksize=512):
    print(df.shape)

  • chunkごとに読み込みできることは確認できたため、読み込んだデータに対して「何らかの処理」を行った上で、別ファイルに保存する(つまり、小さいサイズで処理した後に保存する)
  • 出力ではheaderの有無を明示的に指定する
  • 「header=i == 0」と指定することで「i == 0」、すなわち1chunk目のみheader有りで出力するようにし、2chunk目以降はheaderなしで出力する
# chunkごとに読み込みできることは確認できたため、読み込んだデータに対して「何らかの処理」を行った上で、別ファイルに保存する(つまり、小さいサイズで処理した後に保存する)
# chunk64で読み込んだ分ずつ、CSVへ出力している
i = 0
for df in pd.read_csv(big_data, chunksize=64):
    df['processd_per_chunk'] = True
    # mode='a':追記
    # 出力ではheaderの有無を明示的に指定する
    # 「header=i == 0」と指定することで「i == 0」、すなわち1chunk目のみheader有りで出力するようにし、
    # 2chunk目以降はheaderなしで出力する
    df.to_csv('test_processed_big_data.csv', mode='a', index=False, header=i == 0)
    i += 1
# CSV出力
df = pd.read_csv('test_processed_big_data.csv')