web-dev-qa-db-fra.com

multitraitement pandas s'appliquent

J'essaie d'utiliser le multitraitement avec pandas dataframe, qui consiste à diviser le cadre de données en 8 parties. appliquer une fonction à chaque partie en utilisant apply (avec chaque partie traitée dans un processus différent).

EDIT: Voici la solution que j'ai finalement trouvée:

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 __== '__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'])
15
yemu

Comme je n'ai pas beaucoup de votre script de données, c'est une hypothèse, mais je suggérerais d'utiliser p.map au lieu de apply_async avec le rappel.

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

Une version plus générique basée sur la solution author, qui permet de l'exécuter sur chaque fonction et chaque image:

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)

Donc, la ligne suivante:

df.apply(some_func, axis=1)

Va devenir:

parallelize_on_rows(df, some_func) 
2
Tom Raz

Je rencontre également le même problème lorsque j'utilise multiprocessing.map() pour appliquer une fonction à un bloc différent d'une grande trame de données.

Je veux juste ajouter plusieurs points au cas où d’autres personnes rencontreraient le même problème que moi.

  1. n'oubliez pas d'ajouter if __== '__main__':
  2. exécuter le fichier dans un fichier .py; si vous utilisez ipython/jupyter notebook, vous ne pouvez pas exécuter multiprocessing (ceci est vrai pour mon cas, bien que je n'en ai aucune idée)
0
user6651227