今日、仕事で数ギガにもなるファイルを読込み、前処理を行うという作業を行ったのでそのTipsをメモしていく。
read_csvの便利な機能:chuncsize=(分割したい行数)
ギガを超えるファイルを通常の要領(read_csv)で読込んでDataFrameにしようとすると、一発でメモリエラーを起こします。
そこで助けられたのがこいつ
read_csvのチャンク機能!
この機能は大容量ファイルに対して指定した行数ずつ読み込んでいくことができる機能で、大容量ファイルを一発で全て読み込むことを回避することができます。
分割したところで結局大容量ファイルを読み込むんだったら結果一緒なんじゃないの?
それが、回避方法があるんですよ!
早速コードを見ていきましよう。
以下に示すコードは、大容量ファイルが複数あり、すべてを読み込む必要がある場合を想定しています。
もちろんファイルが一つでも動きます。
import pandas as pd
import glob
flist = glob.glob('...') # 読み取りたいファイルまでのパスを指定
def maeshori(r):
# 分割したデータを軽くするための処理を行う
# 例えば、以下のように分析に必要な列だけを取り出す等
return r[['カラム1','カラム2','カラム3']]
for f in flist:
reader = pd.read_csv(f,encoting='utf_8_sig',chunksize=100000) ♯ 10万行ずつ読み込むように指定
tmp = pd.concat(maeshori(r) for r in reader), ignore_index=True)
df = pd.concat([df,tmp])
print(df.shape)
流れとしては、
- globを使って読み取りたいファイルのパスを指定
- ファイル一つ一つに対して、chuncksizeで指定した数量(ここでは10万行)ずつ読み込み、その結果をreaderに格納する
- readerに格納されているデータに対して、自作関数maeshori()でデータ内容を軽くしながらDataFrameに格納していく
といった感じです。
自作関数については、多くの場合データ分析において全カラムを使うケースは少ないので自作関数”maeshori”で必要な列のみ抽出しています。
def maeshori(r):
# 分割したデータを軽くするための処理を行う
# 例えば、以下のように分析に必要な列だけを取り出す等
return r[['カラム1','カラム2','カラム3']]
必要に応じて自作関数の部分は変更してください。
以上のようにすることで、大容量ファイルのデータをメモリに乗せることなく、分割して効率的に読み込むことができます。
きっとメモリエラーを回避することができるでしょう!
コメント