2017-08-23 3 views
1

私はこれがDASKのバグやPythonの機能がある場合はわからないラムダ関数のループに適用されます。簡単な例:奇妙な挙動は

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] 

私はDASKを使用して、各タグ

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

ための "ホット列" を作成したい:

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)) 
でデフォルト値を使用します