81

複数のパラメーターを受け入れる pool.map() 内で関数を使用する方法が必要です。私の理解によると、pool.map() のターゲット関数はパラメーターとしてイテラブルを 1 つしか持つことができませんが、他のパラメーターも渡す方法はありますか? この場合、Lock() やログ情報などのいくつかの構成変数をターゲット関数に渡す必要があります。

いくつかの調査を試みましたが、部分関数を使用して機能させることができると思いますか? しかし、私はこれらがどのように機能するかを完全には理解していません。どんな助けでも大歓迎です!これが私がやりたいことの簡単な例です:

def target(items, lock):
    for item in items:
        # Do cool stuff
        if (... some condition here ...):
            lock.acquire()
            # Write to stdout or logfile, etc.
            lock.release()

def main():
    iterable = [1, 2, 3, 4, 5]
    pool = multiprocessing.Pool()
    pool.map(target(PASS PARAMS HERE), iterable)
    pool.close()
    pool.join()
4

3 に答える 3

150

これに使用できますfunctools.partial(疑ったように):

from functools import partial

def target(lock, iterable_item):
    for item in iterable_item:
        # Do cool stuff
        if (... some condition here ...):
            lock.acquire()
            # Write to stdout or logfile, etc.
            lock.release()

def main():
    iterable = [1, 2, 3, 4, 5]
    pool = multiprocessing.Pool()
    l = multiprocessing.Lock()
    func = partial(target, l)
    pool.map(func, iterable)
    pool.close()
    pool.join()

例:

def f(a, b, c):
    print("{} {} {}".format(a, b, c))

def main():
    iterable = [1, 2, 3, 4, 5]
    pool = multiprocessing.Pool()
    a = "hi"
    b = "there"
    func = partial(f, a, b)
    pool.map(func, iterable)
    pool.close()
    pool.join()

if __name__ == "__main__":
    main()

出力:

hi there 1
hi there 2
hi there 3
hi there 4
hi there 5
于 2014-08-28T16:44:54.833 に答える
11

multiprocessingfound inの fork と同様に、複数の引数を許可する map 関数を使用できますpathos

>>> from pathos.multiprocessing import ProcessingPool as Pool
>>> 
>>> def add_and_subtract(x,y):
...   return x+y, x-y
... 
>>> res = Pool().map(add_and_subtract, range(0,20,2), range(-5,5,1))
>>> res
[(-5, 5), (-2, 6), (1, 7), (4, 8), (7, 9), (10, 10), (13, 11), (16, 12), (19, 13), (22, 14)]
>>> Pool().map(add_and_subtract, *zip(*res))
[(0, -10), (4, -8), (8, -6), (12, -4), (16, -2), (20, 0), (24, 2), (28, 4), (32, 6), (36, 8)]

pathosを使用すると、複数の入力を持つ階層的な並列マップを簡単にネストできるため、例を拡張してそれを実証できます。

>>> from pathos.multiprocessing import ThreadingPool as TPool
>>> 
>>> res = TPool().amap(add_and_subtract, *zip(*Pool().map(add_and_subtract, range(0,20,2), range(-5,5,1))))
>>> res.get()
[(0, -10), (4, -8), (8, -6), (12, -4), (16, -2), (20, 0), (24, 2), (28, 4), (32, 6), (36, 8)]

さらに楽しいのは、Pool に渡すことができるネストされた関数を作成することです。これは、Python でほとんど何でもシリアル化できる をpathos使用しているため可能です。dill

>>> def build_fun_things(f, g):
...   def do_fun_things(x, y):
...     return f(x,y), g(x,y)
...   return do_fun_things
... 
>>> def add(x,y):
...   return x+y
... 
>>> def sub(x,y):
...   return x-y
... 
>>> neato = build_fun_things(add, sub)
>>> 
>>> res = TPool().imap(neato, *zip(*Pool().map(neato, range(0,20,2), range(-5,5,1))))
>>> list(res)
[(0, -10), (4, -8), (8, -6), (12, -4), (16, -2), (20, 0), (24, 2), (28, 4), (32, 6), (36, 8)]

ただし、標準ライブラリの外に出られない場合は、別の方法で行う必要があります。その場合の最善の策は、ここに示すように使用するmultiprocessing.starmapことです:複数の引数の Python multiprocessing pool.map (OP の投稿のコメントで @Roberto によって指摘されています)

pathosここにアクセスしてください: https://github.com/uqfoundation

于 2015-03-20T21:04:32.467 に答える