2017-01-19 9 views
2

私は私の問題を解決するためのループではなく、ラムダ関数を使用することを好むパンダのデータフレームを持っています。パイソン - 複数の列上のラムダ関数は

問題はそうです。

df = pd.DataFrame({'my_fruits':['fruit', 'fruit', 'fruit', 'fruit', 'fruit'], 
     'fruit_a': ['apple', 'banana', 'vegetable', 'vegetable', 'cherry'], 
     'fruit_b': ['vegetable', 'apple', 'vegeatble', 'pineapple', 'pear']}) 

次のループを適用すると、

for i in np.arange(0,len(df)): 
    if df['fruit_a'][i] == 'vegetable' or df['fruit_b'][i] == 'vegetable': 
     df['my_fruits'][i] = 'not_fruit' 

私は私が望む結果を得ることができています。これは、値vegetableを含むfruit_aまたはfruit_b列のいずれかであれば、私はmy_fruits列がnot_fruitに等しくなるようにしたいということです。

どのように私は可能なラムダ関数内でこれを設定することができます。 2つの列の入力を使用して異なる列の値を変更する方法を理解できませんでした。ありがとう!

あなたが boolean maskSeries.maskを使用することができます
+1

私は質問をしません。ラムダ*式*は、関数本体が 'return 'のみで構成される特別な場合に関数を定義するための代替構文です。関数は 'for'ループの代替手段ではありません。 forループの特定の特殊ケースの代わりに、理解がありますが、ループはそのような特別なケースではありません。 –

答えて

3

mask = (df['fruit_a'] == 'vegetable') | (df['fruit_b'] == 'vegetable') 
print (mask) 
0  True 
1 False 
2  True 
3  True 
4 False 
dtype: bool 


df.my_fruits = df.my_fruits.mask(mask, 'not_fruits') 
print (df) 
    fruit_a fruit_b my_fruits 
0  apple vegetable not_fruits 
1  banana  apple  fruit 
2 vegetable vegetable not_fruits 
3 vegetable pineapple not_fruits 
4  cherry  pear  fruit 

maskための別の解決策は、vegetableによって選択されたすべての列を比較して、anyすることにより、少なくとも1つの列のすべてのTrueを取得することです:

print ((df[['fruit_a', 'fruit_b']] == 'vegetable')) 
    fruit_a fruit_b 
0 False True 
1 False False 
2 True True 
3 True False 
4 False False 

mask = (df[['fruit_a', 'fruit_b']] == 'vegetable').any(axis=1) 
print (mask) 
0  True 
1 False 
2  True 
3  True 
4 False 
dtype: bool 
+0

代替方法の方が非常に高く評価されています –

+0

受け入れていただきありがとうございます。 – jezrael

1

あなたはapplyメソッドでこれを行うことができます。

>>> df.my_fruits = df.apply(lambda x: 'not_fruit' if x['fruit_a'] == 'vegetable' or x['fruit_b'] == 'vegetable' else x['my_fruits'], axis=1) 
0 not_fruit 
1  fruit 
2 not_fruit 
3 not_fruit 
4  fruit 

それともあなたはこのようにそれを行うことができます。'vegetable'場合anyと組み合わせてワンステップで

>>> df.my_fruits[(df['fruit_a'] == 'vegetable') | (df['fruit_b'] == 'vegetable')] = 'not_fruit' 
>>> df 
    fruit_a fruit_b my_fruits 
0  apple vegetable not_fruit 
1  banana  apple  fruit 
2 vegetable vegeatble not_fruit 
3 vegetable pineapple not_fruit 
4  cherry  pear  fruit 
+0

私は非常に遅い:( – jezrael

+0

はちょうどそれがラムダ関数を使って行うことができる方法 –

+0

確かに、代替ソリューションが優れて見せたかった、合意された。 – jezrael

2

pd.Series.whereを使用してチェックします。
where私はcondの否定を使用する理由であるmaskの反対です。
そうでない場合は、これが私の携帯電話から回答

cond = df[['fruit_a', 'fruit_b']].eq('vegetable').any(1) 
df.my_fruits = df.my_fruits.where(~cond, 'not_fruit') 

に答えるのをjezraelする精神が非常に似ています。タイプミスを許してください。

+0

私はそれをチェックし、それは動作します。 – jezrael