こんにちは、snuowです。
pandasのread_csvで複数のファイルを読み込むときに、「あれ、なんか遅くね?」と思ったことはありませんか?
PCのCPUをフルで使うことで読み込みを高速化したいと思います。
multiprocessing.Poolを使って高速化
multiprocessing.Poolを使用して、read_csvを並列化処理し読み込みの高速化を図ります。
multiprocessing.Poolを使用すると、CPUのコア毎に読み込み処理を割り当てることができるので、CPUのコア数分高速に読み込みができるようになります。
jupyter-notebook以外の方は、高速化するためのコード例を見てください。今回ご紹介するコードでは、CPUコアをすべて使用して並列化を行います。
multiprocessing.Poolの問題
Windows機でjupyter-notebookを使用している方は、multiprocessing.Poolで高速化するのに注意が必要です。工夫をしないと、並列化ができません。
下記に示すようにコーディングを行うと、実行した最終セルだけ終了しなくなりました。(そもそも始まっていない?)

jupyter-notebookでなければ、上記のコードが実行できるはずなので、試してほしいと思います。
高速化するためのコード例
それでは、高速化するためのコードを紹介したいと思います。
なお、jupyter-notebookの場合は、下記に示すように別のファイルに関数を保存し、importすることで動作させることができます。
その他のIDE等を使用されている場合は、関数をそのままコピペすれば使用できるようになります。
.ipynb
と同じフォルダに下記のコードをコピーする- 同フォルダに
__init__.py
ファイルを置く - Jupyter-notebook上で、funcをimportして実行する
import pandas as pd import os,glob from datetime import datetime as dt from multiprocessing import Pool FOLDER_PATH = r'folder_path\\' FILE_TYPE = r'*.csv' FILE_FORMAT = 'Report_%Y%m%d.csv' def read_report_to_dataframe(): # ファイルパスをリスト化 csv_pathlist = glob.glob(FOLDER_PATH + FILE_TYPE) # 下記のコードで、CPUコアをすべて使用して並列化処理をします。 with Pool(os.cpu_count()) as p: df = pd.concat(p.map(read_report, csv_pathlist)) return df # report読み込み def read_report(csv_path): separator_list = [';',','] for sep in separator_list: df = pd.read_csv(filepath_or_buffer=csv_path, engine='python', parse_dates=[0], index_col=[0], skiprows=[1], nrows=96, sep=sep) # データフレームが空か確認 if not df.empty: break return df
下記のコードが並列化処理の部分になります。下記では、CPUのコアをすべて使用して並列化処理を行うため、CPUの使用率は100%になりますので注意してください。
# 下記のコードで、CPUコアをすべて使用して並列化処理をします。 with Pool(os.cpu_count()) as p: df = pd.concat(p.map(read_report, csv_pathlist))
jupyter-notebookでは、上記のコードをimportし読みだして実行します。
import func func.read_report_to_dataframe()
いかがだったでしょうか。実行速度の検証を行っていませんが、簡単に高速化ができることが分かったかと思います。
ぜひ、たくさんのファイルを読み込む際に試してもらえればと思います。
コメント