Dans la bibliothèque de multitraitement Python, y at-il une variante de pool.map supportant plusieurs arguments ?
Réponses
Trop de publicités?est-il une variante de la piscine.carte prenant en charge plusieurs arguments?
Python 3.3 inclut
pool.starmap()
méthode.Pour les anciennes versions:
import itertools from multiprocessing import Pool, freeze_support def func(a, b): print a, b def func_star(a_b): """Convert `f([1,2])` to `f(1,2)` call.""" return func(*a_b) def main(): pool = Pool() a_args = [1,2,3] second_arg = 1 pool.map(func_star, itertools.izip(a_args, itertools.repeat(second_arg))) if __name__=="__main__": freeze_support() main()
Sortie
1 1 2 1 3 1
Remarquez comment
itertools.izip()
etitertools.repeat()
sont utilisés ici.En raison de la bogue mentionné par @unutbu vous ne pouvez pas utiliser
functools.partial()
ou des fonctionnalités similaires à la version 2.6 de Python, de sorte que la simple fonction wrapperfunc_star()
doit être définie de manière explicite. Voir aussi la solution proposée paruptimebox
.
Ma première pensée a été d'utiliser des partial
, et celle de J. F. Sebastian indiqué, partial
fonctionne dans cet exemple en Python >=2.7, donc je suis ce détachement, avec la mise en garde qu'il ne fonctionne pas en 2.6.
Notez également que dans le code ci-dessus, vous êtes de passage le résultat d' harvester(text, case)
au lieu de la fonction harvester
lui-même. Aussi, vous n'êtes pas de retourner quoi que ce soit; vous aurez à retourner quelque chose pour que ce soit utile.
Je suppose qu' text
est la variable qui doit être mappé, tandis que fournit la fonction de mappage des informations supplémentaires sur l'ensemble de la séquence. Il suffit de cartes de chaque élément en case
de case[i] + case[0]
. C'est un peu différent de ce que vous avez fait, mais je trouve cet exemple plus clair:
from functools import partial
def harvester(text, case):
X = case[0]
return text + str(X)
partial_harvester = partial(harvester, case=RAW_DATASET)
if __name__ == '__main__':
pool = multiprocessing.Pool(processes=6)
case_data = RAW_DATASET
pool.map(partial_harvester, case_data, 1)
pool.close()
pool.join()
J. F. Sebastian's réponse est plus général, car il vous permet de spécifier unique arguments pour chaque appel. Mais à l'aide de partial
est plus simple lorsque l'un des arguments reste le même pour tous les appels.
Ayant appris itertools dans J. F. Sebastian réponse, j'ai décidé de franchir une nouvelle étape et d'écrire un parmap
package qui prend garde à la parallélisation, offrant map
et starmap
des fonctions en python 2.7 et python 3.2 (et plus tard aussi) qui peut prendre n'importe quel nombre d'arguments de position.
Installation
pip install parmap
Comment paralléliser:
import parmap
# If you want to do:
y = [myfunction(x, argument1, argument2) for x in mylist]
# In parallel:
y = parmap.map(myfunction, mylist, argument1, argument2)
# If you want to do:
z = [myfunction(x, y, argument1, argument2) for (x,y) in mylist]
# In parallel:
z = parmap.starmap(myfunction, mylist, argument1, argument2)
# If you want to do:
listx = [1, 2, 3, 4, 5, 6]
listy = [2, 3, 4, 5, 6, 7]
param = 3.14
param2 = 42
listz = []
for (x, y) in zip(listx, listy):
listz.append(myfunction(x, y, param1, param2))
# In parallel:
listz = parmap.starmap(myfunction, zip(listx, listy), param1, param2)
J'ai téléchargé parmap de PyPI et à un dépôt github.
Par exemple, la question peut être répondu comme suit:
import parmap
def harvester(case, text):
X = case[0]
text+ str(X)
if __name__ == "__main__":
case = RAW_DATASET # assuming this is an iterable
parmap.map(harvester, case, "test", chunksize=1)
Il y a une fourchette de multiprocessing
appelé le pathos (note: utiliser la version sur github) qui n'a pas besoin d' starmap
-- des fonctions de la carte miroir de l'API python de la carte, et donc de la carte peut prendre plusieurs arguments. Avec pathos
, vous pouvez généralement faire le multitraitement dans l'interprète, au lieu d'être coincé dans l' __main__
bloc. Le Pathos est due pour une sortie, après une légère mise à jour-la plupart du temps la conversion de python 3.x.
Python 2.7.5 (default, Sep 30 2013, 20:15:49)
[GCC 4.2.1 (Apple Inc. build 5566)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def func(a,b):
... print a,b
...
>>>
>>> from pathos.multiprocessing import ProcessingPool
>>> pool = ProcessingPool(nodes=4)
>>> pool.map(func, [1,2,3], [1,1,1])
1 1
2 1
3 1
[None, None, None]
>>>
>>> # also can pickle stuff like lambdas
>>> result = pool.map(lambda x: x**2, range(10))
>>> result
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>>
>>> # also does asynchronous map
>>> result = pool.amap(pow, [1,2,3], [4,5,6])
>>> result.get()
[1, 32, 729]
>>>
>>> # or can return a map iterator
>>> result = pool.imap(pow, [1,2,3], [4,5,6])
>>> result
<processing.pool.IMapIterator object at 0x110c2ffd0>
>>> list(result)
[1, 32, 729]