2017-12-08 13 views
0

何十万行ものpandas DataFrameがあり、そのDataFrameの複数の列にパラレルで時間のかかる関数を適用したいと考えています。pandas DataFrameの複数の列に並列に関数を適用する方法

私は関数を連続的に適用する方法を知っています。たとえば:

import hashlib 

import pandas as pd 


df = pd.DataFrame(
    {'col1': range(100_000), 'col2': range(100_000, 200_000)}, 
    columns=['col1', 'col2']) 


def foo(col1, col2): 
    # This function is actually much more time consuming in real life 
    return hashlib.md5(f'{col1}-{col2}'.encode('utf-8')).hexdigest() 


df['md5'] = df.apply(lambda row: foo(row.col1, row.col2), axis=1) 

df.head() 
# Out[5]: 
# col1 col2        md5 
# 0  0 100000 92e2a2c7a6b7e3ee70a1c5a5f2eafd13 
# 1  1 100001 01d14f5020a8ba2715cbad51fd4c503d 
# 2  2 100002 c0e01b86d0a219cd71d43c3cc074e323 
# 3  3 100003 d94e31d899d51bc00512938fc190d4f6 
# 4  4 100004 7710d81dc7ded13326530df02f8f8300 

しかし、どのように私は自分のマシン上のすべての利用可能なコアを利用し、機能foo平行に適用されますでしょうか?

答えて

1

最も簡単な方法はconcurrent.futuresです。各プロセスが一度に1000行を処理するためchunksize=1_000を指定

import concurrent.futures 

with concurrent.futures.ProcessPoolExecutor(16) as pool: 
    df['md5'] = list(pool.map(foo, df['col1'], df['col2'], chunksize=1_000)) 

df.head() 
# Out[10]: 
# col1 col2        md5 
# 0  0 100000 92e2a2c7a6b7e3ee70a1c5a5f2eafd13 
# 1  1 100001 01d14f5020a8ba2715cbad51fd4c503d 
# 2  2 100002 c0e01b86d0a219cd71d43c3cc074e323 
# 3  3 100003 d94e31d899d51bc00512938fc190d4f6 
# 4  4 100004 7710d81dc7ded13326530df02f8f8300 

(すなわち、あなたは一度だけ1000行あたりのプロセスの初期化のオーバーヘッドを支払うことになります)より早くこの実行します。

これはPython 3.2以降でのみ機能することに注意してください。

関連する問題