2010-12-16 18 views
11

Pythonではmultiprocessingモジュールを使用して、ある範囲の値に対して並列に関数を実行できます。たとえば、fの最初の100000評価のリストが生成されます。Pythonマルチプロセッシング複数の入力を持つ関数

def f(i): 
    return i * i 

def main(): 
    import multiprocessing 
    pool = multiprocessing.Pool(2) 
    ans = pool.map(f, range(100000)) 

    return ans 

fが複数の入力を取りますが、1つの変数だけが変更されても同様のことができますか?たとえば、あなたはこれを並列化する方法を:

def f(i, n): 
    return i * i + 2*n 

def main(): 
    ans = [] 
    for i in range(100000): 
     ans.append(f(i, 20)) 

    return ans 

答えて

11

これを行うにはいくつかの方法があります。質問に与えられた例では、あなただけの

def g(i): 
    return f(i, 20) 

ラッパー関数を定義することができますし、map()に、このラッパーを渡します。 lambda tup: f(*tup):より一般的なアプローチは、単一のタプル引数を取り、複数の引数

def g(tup): 
    return f(*tup) 

または同等のラムダ式を使用するタプルをアンパックラッパーを持つことです。

-3

あなたは貧乏人のカリー化を使用することができます(別名、それをラップ):

new_f = lambda x: f(x, 20) 

その後、new_f(i)を呼び出します。

+3

Thilは、「インポート可能」でない(pickleツールを使用して)機能をサポートしていないため、マルチプロセッシングのマップでは扱いません* – Lagerbaer

21

あなたは、あなたが複数の引数を取るのプールを得ることができますpathosと呼ばれるmultiprocessingの私のフォークを、使用している場合... functools.partial

def f(i, n): 
    return i * i + 2*n 

def main(): 
    import multiprocessing 
    pool = multiprocessing.Pool(2) 
    ans = pool.map(functools.partial(f, n=20), range(100000)) 

    return ans 
3

を使用してもlambda機能を取ることができます。それについての素晴らしい点は、並列に動作するようにプログラミング構造を変更する必要がないことです。

>>> def f(i, n): 
... return i * i + 2*n 
... 
>>> from itertools import repeat 
>>> N = 10000 
>>> 
>>> from pathos.pools import ProcessPool as Pool 
>>> pool = Pool() 
>>> 
>>> ans = pool.map(f, xrange(1000), repeat(20)) 
>>> ans[:10] 
[40, 41, 44, 49, 56, 65, 76, 89, 104, 121] 
>>> 
>>> # this also works 
>>> ans = pool.map(lambda x: f(x, 20), xrange(1000)) 
>>> ans[:10] 
[40, 41, 44, 49, 56, 65, 76, 89, 104, 121] 
関連する問題