Dans la bibliothèque multiprocessing Python, existe-t-il une variante de pool.map qui prend en charge plusieurs arguments?
text = "test"
def harvester(text, case):
X = case[0]
text+ str(X)
if __name__ == '__main__':
pool = multiprocessing.Pool(processes=6)
case = RAW_DATASET
pool.map(harvester(text,case),case, 1)
pool.close()
pool.join()
python
multiprocessing
user642897
la source
la source
partial
nilambda
faire ça. Je pense que cela a à voir avec l'étrange façon dont les fonctions sont transmises aux sous-processus (viapickle
).pool.map(harvester(text,case),case, 1)
par:pool.apply_async(harvester(text,case),case, 1)
return
àharvester()
la réponse de @senderie est devenu inexact. Cela n'aide pas les futurs lecteurs.Réponses:
La réponse à cette question dépend de la version et de la situation. La réponse la plus générale pour les versions récentes de Python (depuis 3.3) a d'abord été décrite ci-dessous par JF Sebastian . 1 Il utilise la
Pool.starmap
méthode, qui accepte une séquence de tuples d'argument. Il décompresse ensuite automatiquement les arguments de chaque tuple et les transmet à la fonction donnée:Pour les versions antérieures de Python, vous devrez écrire une fonction d'assistance pour décompresser explicitement les arguments. Si vous souhaitez l'utiliser
with
, vous devrez également écrire un wrapper pour le transformerPool
en gestionnaire de contexte. (Merci à muon de l' avoir signalé.)Dans les cas plus simples, avec un second argument fixe, vous pouvez également utiliser
partial
, mais uniquement dans Python 2.7+.1. Une grande partie de cela a été inspirée par sa réponse, qui aurait probablement dû être acceptée à la place. Mais comme celui-ci est coincé au sommet, il semblait préférable de l'améliorer pour les futurs lecteurs.
la source
=RAW_DATASET
valeur par défaut àcase
. Sinon, vouspool.map
serez confus au sujet des multiples arguments.text
variable dans votre exemple? Pourquoi estRAW_DATASET
apparemment passé deux fois. Je pense que vous pourriez avoir une faute de frappe?with .. as ..
me donneAttributeError: __exit__
, mais fonctionne très bien si je viens d'appelerpool = Pool();
puis de fermer manuellementpool.close()
(python2.7)Pool
objets ne deviennent pas des gestionnaires de contexte avant Python 3.3. J'ai ajouté une fonction wrapper simple qui renvoie unPool
gestionnaire de contexte.Python 3.3 inclut une
pool.starmap()
méthode :Pour les anciennes versions:
Production
Remarquez comment
itertools.izip()
etitertools.repeat()
sont utilisés ici.En raison du bogue mentionné par @unutbu, vous ne pouvez pas utiliser
functools.partial()
ou des fonctionnalités similaires sur Python 2.6, donc la fonction wrapper simplefunc_star()
doit être définie explicitement. Voir également la solution de contournement suggérée paruptimebox
.la source
func_star
comme ceci:def func_star((a, b))
. Bien sûr, cela ne fonctionne que pour un nombre fixe d'arguments, mais si c'est le seul cas qu'il a, il est plus lisible.f((a,b))
syntaxe est déconseillée et supprimée dans py3k. Et c'est inutile ici.func = lambda x: func(*x)
au lieu de définir une fonction wrapperfunc_star()
ci-dessus)starstarmap
.Je pense que ce qui suit sera meilleur
production
la source
args
directement dansadd
, cela fonctionne pour n'importe quel nombre d'arguments:def add(args): (x,y) = args
lambda
fonction au lieu de définirmulti_run_wrapper(..)
lambda
ne fonctionne pas carpool.map(..)
essaie de décaper la fonction donnéeadd
dans une liste?Utilisation de Python 3.3+ avec
pool.starmap():
Résultat:
Vous pouvez également compresser () d'autres arguments si vous le souhaitez:
zip(a,b,c,d,e)
Dans le cas où vous souhaitez avoir une valeur constante passée comme argument, vous devez utiliser
import itertools
, puiszip(itertools.repeat(constant), a)
par exemple.la source
Ayant appris les outils itert dans la réponse de JF Sebastian, j'ai décidé d'aller plus loin et d'écrire un
parmap
package qui prend en charge la parallélisation, l'offremap
et lesstarmap
fonctions sur python-2.7 et python-3.2 (et plus tard également) qui peut prendre n'importe quel nombre d'arguments positionnels. .Installation
Comment paralléliser:
J'ai téléchargé parmap sur PyPI et dans un dépôt github .
À titre d'exemple, la question peut être répondue comme suit:
la source
# "Comment prendre plusieurs arguments".
la source
Il y a une fourchette de pathos
multiprocessing
appelés ( remarque: utilisez la version sur github ) qui n'a pas besoin - les fonctions de carte reflètent l'API pour la carte de python, donc la carte peut prendre plusieurs arguments. Avec , vous pouvez aussi généralement faire du multitraitement dans l'interpréteur, au lieu d'être coincé dans le bloc. Pathos devrait sortir, après quelques mises à jour légères - principalement une conversion en python 3.x.starmap
pathos
__main__
pathos
a plusieurs façons dont vous pouvez obtenir le comportement exactstarmap
.la source
Vous pouvez utiliser les deux fonctions suivantes afin d'éviter d'écrire un wrapper pour chaque nouvelle fonction:
Utilisez la fonction
function
avec les listes d'argumentsarg_0
,arg_1
etarg_2
comme suit:la source
Une meilleure solution pour python2:
2 3 4
1 2 3
0 1 2
en dehors[]:
[3, 5, 7]
la source
Une autre alternative simple consiste à encapsuler vos paramètres de fonction dans un tuple, puis à encapsuler les paramètres qui doivent également être passés en tuples. Ce n'est peut-être pas idéal lorsqu'il s'agit de grandes quantités de données. Je pense qu'il ferait des copies pour chaque tuple.
Donne la sortie dans un ordre aléatoire:
la source
Une meilleure façon est d'utiliser le décorateur au lieu d'écrire la fonction wrapper à la main. Surtout lorsque vous avez beaucoup de fonctions à cartographier, le décorateur vous fera gagner du temps en évitant d'écrire du wrapper pour chaque fonction. Habituellement, une fonction décorée n'est pas picklable, mais nous pouvons l'utiliser
functools
pour la contourner. Plus de discussions peuvent être trouvées ici .Voici l'exemple
Ensuite, vous pouvez le mapper avec des arguments zippés
Bien sûr, vous pouvez toujours utiliser
Pool.starmap
en Python 3 (> = 3.3) comme mentionné dans d'autres réponses.la source
itertools.product
place dezip
.Une autre façon consiste à passer une liste de listes à une routine à un argument:
On peut alors construire une liste de listes d'arguments avec sa méthode préférée.
la source
Voici une autre façon de le faire, à mon humble avis, plus simple et élégant que toutes les autres réponses fournies.
Ce programme a une fonction qui prend deux paramètres, les imprime et imprime également la somme:
la sortie est:
Consultez la documentation de python pour plus d'informations:
https://docs.python.org/3/library/multiprocessing.html#module-multiprocessing.pool
Assurez-vous en particulier de vérifier la
starmap
fonction.J'utilise Python 3.6, je ne sais pas si cela fonctionnera avec les anciennes versions de Python
Pourquoi il n'y a pas un exemple très simple comme celui-ci dans les documents, je ne suis pas sûr.
la source
À partir de python 3.4.4, vous pouvez utiliser multiprocessing.get_context () pour obtenir un objet contextuel pour utiliser plusieurs méthodes de démarrage:
Ou vous remplacez simplement
par:
la source
Il existe de nombreuses réponses ici, mais aucune ne semble fournir de code compatible Python 2/3 qui fonctionnera sur n'importe quelle version. Si vous voulez que votre code fonctionne , cela fonctionnera pour l'une ou l'autre version de Python:
Après cela, vous pouvez utiliser le multitraitement de la manière Python 3 habituelle, comme vous le souhaitez. Par exemple:
fonctionnera en Python 2 ou Python 3.
la source
Dans la documentation officielle, il ne prend en charge qu'un seul argument itérable. J'aime utiliser apply_async dans de tels cas. Dans votre cas, je ferais:
la source
la source
Voici un exemple de la routine que j'utilise pour passer plusieurs arguments à une fonction à un argument utilisée dans un fork pool.imap :
la source
pour python2, vous pouvez utiliser cette astuce
la source