如何将多个参数传递给dask.distributed.Client()。map?

时间:2019-03-02 23:03:39

标签: dask dask-distributed

import dask.distributed
def f(x, y):
    return x, y
client = dask.distributed.Client()
client.map(f, [(1, 2), (2, 3)])

不起作用。

[<Future: status: pending, key: f-137239e2f6eafbe900c0087f550bc0ca>,
 <Future: status: pending, key: f-64f918a0c730c63955da91694fcf7acc>]

distributed.worker - WARNING -  Compute Failed
Function:  f
args:      ((1, 2))
kwargs:    {}
Exception: TypeError("f() missing 1 required positional argument: 'y'",)

distributed.worker - WARNING -  Compute Failed
Function:  f
args:      ((2, 3))
kwargs:    {}
Exception: TypeError("f() missing 1 required positional argument: 'y'",)

2 个答案:

答案 0 :(得分:2)

您没有足够的签名权-也许文档不清晰(欢迎提出建议)。 Client.map()为提交的每个任务采用(可变数量的)参数集,而不是单个可迭代的事物。您应该将其表达为

client.map(f, (1, 2), (2, 3))

或者,如果您想更接近原始图案

client.map(f, *[(1, 2), (2, 3)])

答案 1 :(得分:0)

好吧,documentation对此肯定有点令人困惑。而且我找不到一个清楚地证明了这个问题的例子。因此,我将其分解如下:

def test_fn(a, b, c, d, **kwargs):
    return a + b + c + d + kwargs["special"]

futures = client.map(test_fn, *[[1, 2, 3, 4], (1, 2, 3, 4), (1, 2, 3, 4), (1, 2, 3, 4)], special=100)
output = [f.result() for f in futures]
# output = [104, 108, 112, 116]

futures = client.map(test_fn, [1, 2, 3, 4], (1, 2, 3, 4), (1, 2, 3, 4), (1, 2, 3, 4), special=100)
output = [f.result() for f in futures]
# output = [104, 108, 112, 116]

注意事项:

  1. 使用列表还是元组都没关系。就像我上面所做的一样,您可以将它们混合。
  2. 您必须按参数的位置将其分组。因此,如果要传入4组参数,则第一个列表将包含所有4组参数中的第一个参数。 (在这种情况下,对test_fn的“首次”调用将获得a = b = c = d = 1。)
  3. 额外的**kwargs(如special)将传递给该函数。但是所有函数调用的值都相同。

现在我考虑一下,这并不奇怪。我认为它只是遵循Python的concurrent.futures.ProcessPoolExecutor.map()签名。

PS。请注意,即使文档中显示“ Returns:
列表,迭代器或期货队列,具体取决于期货的类型 输入”。实际上,您会收到此错误:Dask no longer supports mapping over Iterators or Queues. Consider using a normal for loop and Client.submit