2017-08-23 69 views
1

我不確定這是否是dask或Python的一個功能的缺陷。簡單的例子:dask中的奇怪行爲適用於lambda函數循環

data = pd.DataFrame({'tags': [['dog'], ['cat', 'red'], ['cat'], ['cat', 'red'], ['cat', 'red'], ['dog', 'red']]}) 
print data 

      tags 
0  [dog] 
1 [cat, red] 
2  [cat] 
3 [cat, red] 
4 [cat, red] 
5 [dog, red] 

我想每個標籤

tags = ['cat', 'dog', 'red'] 

打造 「熱列」 使用DASK:

data = dd.from_pandas(data, npartitions=4) 

for tag in tags: 
    data[tag] = data.tags.apply(lambda x: tag in x, meta=(tag, bool)) 

結果是錯誤的:

print data.compute() 
     tags cat dog red 
0  [dog] False False False 
1 [cat, red] True True True 
2  [cat] False False False 
3 [cat, red] True True True 
4 [cat, red] True True True 
5 [dog, red] True True True 

似乎是lambda始終與循環中的最後一個標記相關(red)。如果我手動展開循環,它可以正常工作。

使用普通熊貓我沒有這個問題。

部分解決

def is_in(items, value): 
    return value in items 

for tag in tags: 
    data[tag] = data.tags.apply(is_in, value=tag, meta=(tag, bool)) 

我不很喜歡它,因爲它迫使參數的順序是相當不自然。順便說一下,我不確定是否理解了原始問題。

回答

1

答案在這裏:What do (lambda) function closures capture?它是關於蟒蛇的詞彙範圍。

更好的解決方案:拉姆達使用默認值

for tag in tags: 
    data[tag] = data.tags.apply(lambda x, t=tag: t in x, meta=(tag, bool))