web-dev-qa-db-ja.com

pandasマルチプロセッシングが適用されます

pandas dataframe、つまりデータフレームを8つの部分に分割して)マルチプロセッシングを使用しようとしています。applyを使用して各部分に関数を適用します(各部分は異なるプロセスで処理されます)。

編集:私が最終的に見つけた解決策は次のとおりです:

import multiprocessing as mp
import pandas.util.testing as pdt

def process_apply(x):
    # do some stuff to data here

def process(df):
    res = df.apply(process_apply, axis=1)
    return res

if __name__ == '__main__':
    p = mp.Pool(processes=8)
    split_dfs = np.array_split(big_df,8)
    pool_results = p.map(aoi_proc, split_dfs)
    p.close()
    p.join()

    # merging parts processed by different processes
    parts = pd.concat(pool_results, axis=0)

    # merging newly calculated parts to big_df
    big_df = pd.concat([big_df, parts], axis=1)

    # checking if the dfs were merged correctly
    pdt.assert_series_equal(parts['id'], big_df['id'])
32
yemu

著者のソリューションに基づくより一般的なバージョンで、すべての関数とデータフレームで実行できます。

from multiprocessing import  Pool
from functools import partial
import numpy as np

def parallelize(data, func, num_of_processes=8):
    data_split = np.array_split(data, num_of_processes)
    pool = Pool(num_of_processes)
    data = pd.concat(pool.map(func, data_split))
    pool.close()
    pool.join()
    return data

def run_on_subset(func, data_subset):
    return data_subset.apply(func, axis=1)

def parallelize_on_rows(data, func, num_of_processes=8):
    return parallelize(data, partial(run_on_subset, func), num_of_processes)

したがって、次の行:

df.apply(some_func, axis=1)

となります:

parallelize_on_rows(df, some_func) 
11
Tom Raz

データスクリプトがあまりないので、これは推測ですが、コールバックではp.mapではなくapply_asyncを使用することをお勧めします。

p = mp.Pool(8)
pool_results = p.map(process, np.array_split(big_df,8))
p.close()
p.join()
results = []
for result in pool_results:
    results.extend(result)
4
Rafael Barros

次の例のように、 https://github.com/nalepae/pandarallel を使用できます。

from pandarallel import pandarallel
from math import sin

pandarallel.initialize()

def func(x):
    return sin(x**2)

df.parallel_apply(func, axis=1)

2

multiprocessing.map()を使用して大きなデータフレームの別のチャンクに関数を適用すると、同じ問題が発生します。

他の人が私と同じ問題に遭遇した場合に備えて、いくつかのポイントを追加したいだけです。

  1. if __name__ == '__main__':を忘れずに追加してください
  2. .pyファイルでファイルを実行します。ipython/jupyter notebookを使用すると、multiprocessingを実行できません(これは私の場合に当てはまりますが、手がかりはありません)
0
user6651227

これは私にとってうまくいきました:

rows_iter = (row for _, row in df.iterrows())

with multiprocessing.Pool() as pool:
    df['new_column'] = pool.map(process_apply, rows_iter)
0
EliadL

インストール Pyxtension 並列マップの使用を簡素化し、次のように使用します。

from pyxtension.streams import stream

big_df = pd.concat(stream(np.array_split(df, multiprocessing.cpu_count())).mpmap(process))
0
asu