【python】jupyterのpandasで高速にcsvを読み込む方法【multiprocessing】

Python

こんにちは、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等を使用されている場合は、関数をそのままコピペすれば使用できるようになります。

  1. .ipynbと同じフォルダに下記のコードをコピーする
  2. 同フォルダに__init__.pyファイルを置く
  3. 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()

いかがだったでしょうか。実行速度の検証を行っていませんが、簡単に高速化ができることが分かったかと思います。

ぜひ、たくさんのファイルを読み込む際に試してもらえればと思います。

コメント

タイトルとURLをコピーしました