2016-03-03 48 views
2

在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中表現出來,這將需要顯式轉換爲列表。

所以,計算foldresult.compute())時, 是add_to_count 輸入參數x發電機,或已它已經被轉換爲一個列表?

我感興趣的情況下列表非常長, 和這麼懶的評價是更有效的,比方說, b1 = db.from_sequence([10**6]*10)

我猜我還可以與bag.frequencies解決上述問題,但我對懶惰的評價和有效的減少類似的關切。

有沒有,我不是所著的Grokking,還是我只是懶惰DASK的一個基本方面,並在可能我特地到代碼算出這個我自己?

+0

好,很輕鬆了,加上'打印(式(X))''來add_to_count()',並與不同的調度試圖似乎證實'x'確實是一個生成器對象。如果有任何要添加的東西,我會稍微打開一下。 –

回答

2

不完全合適,但我會提供答案,以一個稍微不同的問題:

Dask.bag在防守調用增加list`你,萬一你決定另闢蹊徑,用袋子在一個單一的計算兩次:

x = b.map(func1, b) 
y = b.map(func2, b) 
compute(x.frequencies(), b.frequencies()) 

當使用像多後端或分佈式的,因爲我們不能跨進程邊界發送發電機,但可以發送名單,這也是有用的。

然而,list這些防禦調用時可能在努力促進懶惰計算之前優化掉。

總之,一切應該只是工作你想要的方式時,儘可能,但會恢復到具體的非懶惰值,當懶惰會妨礙正確的方式。

+0

謝謝。這正是我所期待的。這是在任何地方的文檔概述(我找不到它),它會有用嗎?如果你這麼認爲,我可以藉助一些幫助來刺探它。 –

+0

據我所知,不在文檔中。總是感謝幫助。 – MRocklin