生成器何时转换为 Dask 中的列表?
When are generators converted to lists in Dask?
在 Dask 中,生成器什么时候转换为列表,或者它们通常是延迟使用的?
例如,使用代码:
from collections import Counter
import numpy as np
import dask.bag as db
def foo(n):
for _ in range(n):
yield np.random.randint(10)
def add_to_count(acc, x):
acc.update(x)
return acc
def add(x,y):
return x + y
b1 = db.from_sequence([1,2,3,4,5])
b2 = b1.map(foo)
result = b2.fold(add_to_count, add, Counter())
我得到以下输出,其中生成器
已经(合理地)转换为列表供我检查:
>>> b2.compute()
[[5], [5, 6], [3, 6, 1], [5, 6, 6, 0], [5, 6, 6, 0, 3]]
虽然合理,但它与我通常期望生成器在 Python 中的行为方式不同,后者需要显式转换为列表。
因此,在计算 fold
(result.compute()
) 时,
是 add_to_count
的输入参数 x
生成器,还是已经转换为列表?
我对列表很长的情况很感兴趣,
所以惰性评估更有效,比如说,
b1 = db.from_sequence([10**6]*10)
.
我猜我也可以用 bag.frequencies
解决上述问题,但我对惰性求值和高效归约也有类似的担忧。
Dask 是否有我没有摸索的基本方面,或者我只是懒惰,我在哪里可以查看代码来自己解决这个问题?
不完全合适,但我会提供一个稍微不同的问题的答案:
Dask.bag 为您添加对 list` 的防御性调用,以防万一您决定分支并在一次计算中两次使用包:
x = b.map(func1, b)
y = b.map(func2, b)
compute(x.frequencies(), b.frequencies())
这在使用多处理或分布式等后端时也很有用,因为我们无法跨进程边界发送生成器,但可以发送列表。
但是,这些对 list
的防御性调用会在可能的情况下在计算之前进行优化,以促进懒惰。
总而言之,一切都应该尽可能按照您想要的方式工作,但当惰性妨碍正确性时,将恢复为具体的非惰性值。
在 Dask 中,生成器什么时候转换为列表,或者它们通常是延迟使用的? 例如,使用代码:
from collections import Counter
import numpy as np
import dask.bag as db
def foo(n):
for _ in range(n):
yield np.random.randint(10)
def add_to_count(acc, x):
acc.update(x)
return acc
def add(x,y):
return x + y
b1 = db.from_sequence([1,2,3,4,5])
b2 = b1.map(foo)
result = b2.fold(add_to_count, add, Counter())
我得到以下输出,其中生成器 已经(合理地)转换为列表供我检查:
>>> b2.compute()
[[5], [5, 6], [3, 6, 1], [5, 6, 6, 0], [5, 6, 6, 0, 3]]
虽然合理,但它与我通常期望生成器在 Python 中的行为方式不同,后者需要显式转换为列表。
因此,在计算 fold
(result.compute()
) 时,
是 add_to_count
的输入参数 x
生成器,还是已经转换为列表?
我对列表很长的情况很感兴趣,
所以惰性评估更有效,比如说,
b1 = db.from_sequence([10**6]*10)
.
我猜我也可以用 bag.frequencies
解决上述问题,但我对惰性求值和高效归约也有类似的担忧。
Dask 是否有我没有摸索的基本方面,或者我只是懒惰,我在哪里可以查看代码来自己解决这个问题?
不完全合适,但我会提供一个稍微不同的问题的答案:
Dask.bag 为您添加对 list` 的防御性调用,以防万一您决定分支并在一次计算中两次使用包:
x = b.map(func1, b)
y = b.map(func2, b)
compute(x.frequencies(), b.frequencies())
这在使用多处理或分布式等后端时也很有用,因为我们无法跨进程边界发送生成器,但可以发送列表。
但是,这些对 list
的防御性调用会在可能的情况下在计算之前进行优化,以促进懒惰。
总而言之,一切都应该尽可能按照您想要的方式工作,但当惰性妨碍正确性时,将恢复为具体的非惰性值。