我正在尝试使用dask并行构建字典,但我遇到了TypeError: Delayed objects of unspecified length are not iterable
。
我正在尝试同时计算add
,subtract
和multiply
,以便更快地构建字典。
以下是一些代表我的用例的代码:
import dask
from dask.delayed import delayed
x1 = {'a': 1, 'b': 2, 'c': 3}
x2 = {'a': 4, 'b': 5, 'c': 6}
@delayed
def add(d1, d2):
z = {}
z['func1_a'] = d1['a'] + d2['a']
z['func1_b'] = d1['b'] + d2['b']
z['func1_c'] = d1['c'] + d2['c']
return z
@delayed
def subtract(d1, d2):
z = {}
z['func2_a'] = d1['a'] - d2['a']
z['func2_b'] = d1['b'] - d2['b']
z['func2_c'] = d1['c'] - d2['c']
return z
@delayed
def multiply(d1, d2):
z = {}
z['func3_a'] = d1['a'] * d2['a']
z['func3_b'] = d1['b'] * d2['b']
z['func3_c'] = d1['c'] * d2['c']
return z
@delayed
def last_step(d1, d2):
z = {}
z.update(add(d1, d2))
z.update(subtract(d1, d2))
z.update(multiply(d1, d2))
return z
最后,当我跑:
>>> dask.compute(last_step(x1, x2))
<ipython-input-6-1153797c9d18> in final(d1, d2)
2 def last_step(d1, d2):
3 z = {}
----> 4 z.update(add(d1, d2))
5 z.update(subtract(d1, d2))
6 z.update(multiply(d1, d2))
/Users/me/anaconda3/lib/python3.6/site-packages/dask/delayed.py in __iter__(self)
409 def __iter__(self):
410 if getattr(self, '_length', None) is None:
--> 411 raise TypeError("Delayed objects of unspecified length are "
412 "not iterable")
413 for i in range(self._length):
TypeError: Delayed objects of unspecified length are not iterable
我在这里做错了什么/不理解?
答案 0 :(得分:3)
z
对象是字典,而add
的结果是延迟对象。 update方法需要一个字典。 Python无法知道如何使用一个对象来更新一个dict,这将成为一个dict-when-you-call-compute。
在这种情况下,我建议将z
放入延迟对象
# z = {}
z = delayed({})
z将停止成为一个词典,它将成为一个事物 - 它将成为一个词典。这意味着您不能再检查密钥,使用getitem语法插入密钥,执行任何可变操作,如.update
等,但仍可以在其上调用延迟方法。在你的情况下,我可能会使用像toolz.merge
只是为了设定期望。 Dask.delayed并不完全并行化任意Python代码。你仍然需要做一些工作来考虑对象何时被延迟以及什么是具体的。