J'ai souvent besoin d'appliquer une fonction aux groupes d'un très grand DataFrame
(de types de données mixtes) et je voudrais profiter de plusieurs cœurs.
Je peux créer un itérateur à partir des groupes et utiliser le module multitraitement, mais ce n'est pas efficace car chaque groupe et les résultats de la fonction doivent être picklés pour la messagerie entre les processus.
Existe-t-il un moyen d'éviter le décapage ou même d'éviter la copie du DataFrame
complètement? Il semble que les fonctions de mémoire partagée des modules multiprocesseurs soient limitées aux numpy
tableaux. Il y a-t-il des alternatives?
python
pandas
multiprocessing
shared-memory
user2303
la source
la source
Réponses:
D'après les commentaires ci-dessus, il semble que cela soit prévu depuis un
pandas
certain temps (il y a aussi unrosetta
projet intéressant que je viens de remarquer).Cependant, jusqu'à ce que toutes les fonctionnalités parallèles soient incorporées
pandas
, j'ai remarqué qu'il était très facile d'écrire des augmentations parallèles efficaces et sans copie de mémoirepandas
en utilisant directementcython
+ OpenMP et C ++.Voici un court exemple d'écriture d'un groupby-sum parallèle, dont l'utilisation est quelque chose comme ceci:
et la sortie est:
Remarque Sans aucun doute, la fonctionnalité de cet exemple simple fera éventuellement partie de
pandas
. Cependant, certaines choses seront plus naturelles à paralléliser en C ++ pendant un certain temps, et il est important de savoir à quel point il est facile de les combinerpandas
.Pour ce faire, j'ai écrit une simple extension de fichier source unique dont le code suit.
Cela commence par des importations et des définitions de type
Le
unordered_map
type C ++ est destiné à la sommation par un seul thread et le typevector
est à la somme par tous les threads.Passons maintenant à la fonction
sum
. Il commence par des vues de mémoire typées pour un accès rapide:La fonction continue en divisant le semi-également aux threads (ici codé en dur à 4), et en faisant additionner chaque thread les entrées de sa plage:
Lorsque les threads sont terminés, la fonction fusionne tous les résultats (des différentes plages) en un seul
unordered_map
:Il ne reste plus qu'à créer
DataFrame
et renvoyer les résultats:la source