En la biblioteca de multiprocesamiento de Python, ¿hay una variante de pool.map que admita múltiples argumentos?
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
usuario642897
fuente
fuente
partial
nilambda
hacer esto. Creo que tiene que ver con la extraña forma en que las funciones se pasan a los subprocesos (víapickle
).pool.map(harvester(text,case),case, 1)
por:pool.apply_async(harvester(text,case),case, 1)
return
aharvester()
la respuesta @senderie 's convertido en ser inexacta. Eso no ayuda a los futuros lectores.Respuestas:
La respuesta a esto depende de la versión y la situación. La respuesta más general para las versiones recientes de Python (desde 3.3) fue descrita por primera vez a continuación por JF Sebastian . 1 Utiliza el
Pool.starmap
método, que acepta una secuencia de tuplas de argumentos. Luego, desempaqueta automáticamente los argumentos de cada tupla y los pasa a la función dada:Para versiones anteriores de Python, necesitará escribir una función auxiliar para desempaquetar los argumentos explícitamente. Si desea usar
with
, también necesitará escribir un contenedor para convertirsePool
en un administrador de contexto. (Gracias a muon por señalar esto).En casos más simples, con un segundo argumento fijo, también puede usar
partial
, pero solo en Python 2.7+.1. Gran parte de esto fue inspirado por su respuesta, que probablemente debería haber sido aceptada en su lugar. Pero dado que este está atascado en la parte superior, parecía mejor mejorarlo para futuros lectores.
fuente
=RAW_DATASET
valor predeterminado acase
. Depool.map
lo contrario, se confundirá con los múltiples argumentos.text
variable en tu ejemplo? Por quéRAW_DATASET
aparentemente se pasa dos veces. Creo que podrías tener un error tipográfico?with .. as ..
me daAttributeError: __exit__
, pero funciona bien si acabo de llamarpool = Pool();
a continuación, cierre manualmentepool.close()
(python2.7)Pool
objetos no se convierten en gestores de contexto hasta Python 3.3. He agregado una función de contenedor simple que devuelve unPool
administrador de contexto.Python 3.3 incluye el
pool.starmap()
método :Para versiones anteriores:
Salida
Observe cómo
itertools.izip()
yitertools.repeat()
se usan aquí.Debido al error mencionado por @unutbu, no puede usar
functools.partial()
capacidades similares en Python 2.6, por lo que la función de contenedor simplefunc_star()
debe definirse explícitamente. Consulte también la solución sugerida poruptimebox
.fuente
func_star
la siguiente manera:def func_star((a, b))
. Por supuesto, esto solo funciona para un número fijo de argumentos, pero si ese es el único caso que tiene, es más legible.f((a,b))
sintaxis está en desuso y se elimina en py3k. Y es innecesario aquí.func = lambda x: func(*x)
lugar de definir una función de envolturafunc_star()
anterior)starstarmap
.Creo que lo de abajo será mejor
salida
fuente
args
directamenteadd
, funciona para cualquier número de argumentos:def add(args): (x,y) = args
lambda
función en lugar de definirmulti_run_wrapper(..)
lambda
no funciona porquepool.map(..)
intenta encurtir la función dadaadd
en una lista?Usando Python 3.3+ con
pool.starmap():
Resultado:
También puede comprimir () más argumentos si lo desea:
zip(a,b,c,d,e)
En caso de que desee que se pase un valor constante como argumento, debe usarlo
import itertools
y,zip(itertools.repeat(constant), a)
por ejemplo,fuente
Después de aprender sobre itertools en la respuesta de JF Sebastian , decidí ir un paso más allá y escribir un
parmap
paquete que se ocupara de la paralelización, la ofertamap
y lasstarmap
funciones en python-2.7 y python-3.2 (y más tarde también) que pueden llevar cualquier cantidad de argumentos posicionales .Instalación
Cómo paralelizar:
He subido parmap a PyPI y a un repositorio de github .
Como ejemplo, la pregunta se puede responder de la siguiente manera:
fuente
# "Cómo tomar múltiples argumentos".
fuente
Hay una bifurcación de pathos
multiprocessing
llamado ( nota: use la versión en github ) que no necesita : las funciones de mapa reflejan la API para el mapa de Python, por lo tanto, el mapa puede tomar múltiples argumentos. Con , generalmente también puede hacer multiprocesamiento en el intérprete, en lugar de quedarse atrapado en el bloque. Pathos se lanzará después de una actualización leve, principalmente la conversión a python 3.x.starmap
pathos
__main__
pathos
tiene varias formas de obtener el comportamiento exactostarmap
.fuente
Puede usar las siguientes dos funciones para evitar escribir un contenedor para cada nueva función:
Use la función
function
con las listas de argumentosarg_0
,arg_1
y de laarg_2
siguiente manera:fuente
Una mejor solución para python2:
2 3 4
1 2 3
0 1 2
fuera[]:
[3, 5, 7]
fuente
Otra alternativa simple es envolver sus parámetros de función en una tupla y luego envolver los parámetros que también deberían pasarse en tuplas. Quizás esto no sea ideal cuando se trata de grandes cantidades de datos. Creo que haría copias para cada tupla.
Da la salida en un orden aleatorio:
fuente
Una mejor manera es usar decorador en lugar de escribir la función de envoltura a mano. Especialmente cuando tiene muchas funciones para mapear, el decorador le ahorrará tiempo al evitar el envoltorio de escritura para cada función. Por lo general, una función decorada no es seleccionable, sin embargo, podemos usarla
functools
para evitarla . Más discursos se pueden encontrar aquí .Aquí el ejemplo
Luego puede mapearlo con argumentos comprimidos
Por supuesto, siempre puede usar
Pool.starmap
en Python 3 (> = 3.3) como se menciona en otras respuestas.fuente
itertools.product
lugar dezip
.Otra forma es pasar una lista de listas a una rutina de un argumento:
Uno puede construir una lista de listas de argumentos con su método favorito.
fuente
Aquí hay otra forma de hacerlo, en mi humilde opinión es más simple y elegante que cualquiera de las otras respuestas proporcionadas.
Este programa tiene una función que toma dos parámetros, los imprime y también imprime la suma:
la salida es:
Vea los documentos de Python para más información:
https://docs.python.org/3/library/multiprocessing.html#module-multiprocessing.pool
En particular, asegúrese de revisar la
starmap
función.Estoy usando Python 3.6, no estoy seguro de si esto funcionará con versiones anteriores de Python
Por qué no hay un ejemplo tan sencillo como este en los documentos, no estoy seguro.
fuente
Desde python 3.4.4, puede usar multiprocessing.get_context () para obtener un objeto de contexto para usar múltiples métodos de inicio:
O simplemente reemplazas
por:
fuente
Aquí hay muchas respuestas, pero ninguna parece proporcionar un código compatible con Python 2/3 que funcione en cualquier versión. Si desea que su código simplemente funcione , esto funcionará para cualquier versión de Python:
Después de eso, puede usar el multiprocesamiento de la manera normal de Python 3, como quiera. Por ejemplo:
funcionará en Python 2 o Python 3.
fuente
En la documentación oficial se afirma que solo admite un argumento iterable. Me gusta usar apply_async en tales casos. En tu caso yo haría:
fuente
fuente
Este es un ejemplo de la rutina que uso para pasar múltiples argumentos a una función de un argumento utilizada en una bifurcación pool.imap :
fuente
para python2, puedes usar este truco
fuente