Na biblioteca de multiprocessamento Python, existe uma variante de pool.map que suporta vários 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
user642897
fonte
fonte
partial
nemlambda
fazer isso. Eu acho que tem a ver com a maneira estranha como as funções são passadas para os subprocessos (viapickle
).pool.map(harvester(text,case),case, 1)
por:pool.apply_async(harvester(text,case),case, 1)
return
àharvester()
resposta do @senderie transformada em imprecisa. Isso não ajuda futuros leitores.Respostas:
A resposta para isso é dependente da versão e da situação. A resposta mais geral para versões recentes do Python (desde 3.3) foi descrita pela primeira vez abaixo por JF Sebastian . 1 Ele usa o
Pool.starmap
método, que aceita uma sequência de tuplas de argumento. Em seguida, descompacta automaticamente os argumentos de cada tupla e os passa para a função fornecida:Para versões anteriores do Python, você precisará escrever uma função auxiliar para descompactar os argumentos explicitamente. Se você deseja usar
with
, também precisará escrever um wrapper para se transformarPool
em um gerenciador de contexto. (Obrigado ao muon por apontar isso.)Em casos mais simples, com um segundo argumento fixo, você também pode usar
partial
, mas apenas no Python 2.7+.1. Muito disso foi inspirado em sua resposta, que provavelmente deveria ter sido aceita. Mas como este está preso no topo, parecia melhor melhorá-lo para futuros leitores.
fonte
=RAW_DATASET
valor padrão acase
. Caso contrário,pool.map
irá confundir os vários argumentos.text
variável no seu exemplo? Por queRAW_DATASET
aparentemente é passado duas vezes. Eu acho que você pode ter um erro de digitação?with .. as ..
me dáAttributeError: __exit__
, mas funciona bem se eu apenas chamarpool = Pool();
em seguida, feche manualmentepool.close()
(python2.7)Pool
objetos não se tornam gerenciadores de contexto até o Python 3.3. Eu adicionei uma função de wrapper simples que retorna umPool
gerenciador de contexto.Python 3.3 inclui o
pool.starmap()
método :Para versões mais antigas:
Resultado
Observe como
itertools.izip()
eitertools.repeat()
são usados aqui.Devido ao bug mencionado por @unutbu, você não pode usar
functools.partial()
recursos similares no Python 2.6, portanto, a função simples do wrapperfunc_star()
deve ser definida explicitamente. Consulte também a solução alternativa sugerida poruptimebox
.fonte
func_star
seguinte forma:def func_star((a, b))
. Obviamente, isso funciona apenas para um número fixo de argumentos, mas se esse é o único caso que ele tem, é mais legível.f((a,b))
sintaxe foi descontinuada e removida no py3k. E é desnecessário aqui.func = lambda x: func(*x)
em vez de definir uma função wrapperfunc_star()
acima)starstarmap
.Eu acho que o abaixo será melhor
resultado
fonte
args
diretamenteadd
, ela funciona para qualquer número de argumentos:def add(args): (x,y) = args
lambda
função em vez de definirmulti_run_wrapper(..)
lambda
não funciona porquepool.map(..)
tenta pickle a função dadaadd
uma lista?Usando Python 3.3+ com
pool.starmap():
Resultado:
Você também pode compactar () mais argumentos se desejar:
zip(a,b,c,d,e)
Caso você queira que um valor constante seja passado como argumento, você deve usar
import itertools
e,zip(itertools.repeat(constant), a)
em seguida, por exemplo.fonte
Tendo aprendido sobre itertools na resposta do JF Sebastian , decidi dar um passo adiante e escrever um
parmap
pacote que cuida da paralelização, ofertamap
estarmap
funções no python-2.7 e python-3.2 (e mais tarde também) que podem receber qualquer número de argumentos posicionais .Instalação
Como paralelizar:
Fiz upload do parmap no PyPI e em um repositório do github .
Como exemplo, a pergunta pode ser respondida da seguinte maneira:
fonte
# "Como receber vários argumentos".
fonte
Existe uma bifurcação do
multiprocessing
chamado pathos ( nota: use a versão no github ) que não precisastarmap
- as funções map refletem a API do mapa do python, assim o mapa pode receber vários argumentos. Compathos
, geralmente você também pode fazer multiprocessamento no intérprete, em vez de ficar preso no__main__
bloco. O Pathos deve ser lançado, após algumas atualizações leves - principalmente a conversão para o python 3.x.pathos
tem várias maneiras pelas quais você pode obter o comportamento exato destarmap
.fonte
Você pode usar as duas funções a seguir para evitar escrever um invólucro para cada nova função:
Use a função
function
com as listas de argumentosarg_0
,arg_1
earg_2
como segue:fonte
Uma solução melhor para python2:
2 3 4
1 2 3
0 1 2
Fora[]:
[3, 5, 7]
fonte
Outra alternativa simples é agrupar os parâmetros de função em uma tupla e, em seguida, agrupar os parâmetros que também devem ser passados nas tuplas. Talvez isso não seja o ideal quando se lida com grandes quantidades de dados. Eu acredito que faria cópias para cada tupla.
Fornece a saída em alguma ordem aleatória:
fonte
Uma maneira melhor é usar o decorador em vez de escrever a função do invólucro manualmente. Especialmente quando você tem muitas funções para mapear, o decorador economiza seu tempo evitando escrever wrapper para todas as funções. Normalmente, uma função decorada não é selecionável, no entanto, podemos usá-la
functools
para contorná-la. Mais disscusões podem ser encontradas aqui .Aqui o exemplo
Então você pode mapeá-lo com argumentos compactados
Obviamente, você sempre pode usar
Pool.starmap
no Python 3 (> = 3.3), como mencionado em outras respostas.fonte
itertools.product
vez dezip
.Outra maneira é passar uma lista de listas para uma rotina de um argumento:
Pode-se construir uma lista de argumentos com o método favorito.
fonte
Aqui está outra maneira de fazê-lo: o IMHO é mais simples e elegante do que qualquer outra resposta fornecida.
Este programa possui uma função que aceita dois parâmetros, os imprime e também imprime a soma:
saída é:
Veja os documentos python para mais informações:
https://docs.python.org/3/library/multiprocessing.html#module-multiprocessing.pool
Em particular, verifique a
starmap
função.Estou usando o Python 3.6, não tenho certeza se isso funcionará com versões mais antigas do Python
Por que não há um exemplo muito direto como esse nos documentos, não tenho certeza.
fonte
No python 3.4.4, você pode usar multiprocessing.get_context () para obter um objeto de contexto para usar vários métodos de inicialização:
Ou você simplesmente substitui
de:
fonte
Há muitas respostas aqui, mas nenhuma parece fornecer código compatível com Python 2/3 que funcione em qualquer versão. Se você deseja que seu código funcione , isso funcionará para a versão do Python:
Depois disso, você pode usar o multiprocessamento da maneira regular do Python 3, como quiser. Por exemplo:
funcionará em Python 2 ou Python 3.
fonte
Na documentação oficial afirma que ele suporta apenas um argumento iterável. Eu gosto de usar o apply_async nesses casos. No seu caso, eu faria:
fonte
fonte
Este é um exemplo da rotina que eu uso para passar vários argumentos para uma função de um argumento usada em um fork do pool.imap :
fonte
para python2, você pode usar esse truque
fonte