在Pandas数据帧中的不同列上使用lambda if条件

Pet*_*erL 6 python lambda numpy dataframe pandas

我有简单的数据帧:

import pandas as pd
frame = pd.DataFrame(np.random.randn(4, 3), columns=list('abc'))
Run Code Online (Sandbox Code Playgroud)

例如:

a   b   c
0   -0.813530   -1.291862   1.330320
1   -1.066475   0.624504    1.690770
2   1.330330    -0.675750   -1.123389
3   0.400109    -1.224936   -1.704173
Run Code Online (Sandbox Code Playgroud)

如果c为正,我想创建包含"c"值的列"d".其他值来自"b".

我在尝试:

frame['d']=frame.apply(lambda x: frame['c'] if frame['c']>0 else frame['b'],axis=0)
Run Code Online (Sandbox Code Playgroud)

但得到"ValueError :('系列的真值是不明确的.使用a.empty,a.bool(),a.item(),a.any()或a.all().','发生于索引a')

我试图谷歌如何解决这个问题,但没有成功.有什么提示吗?

Max*_*axU 16

那是你要的吗?

In [300]: frame[['b','c']].apply(lambda x: x['c'] if x['c']>0 else x['b'], axis=1)
Out[300]:
0   -1.099891
1    0.582815
2    0.901591
3    0.900856
dtype: float64
Run Code Online (Sandbox Code Playgroud)

  • axis=1 最后很重要。否则,它会给出 keyerror。 (2认同)

piR*_*red 6

解决方案

使用矢量化方法

frame['d'] = frame.b + (frame.c > 0) * (frame.c - frame.b)
Run Code Online (Sandbox Code Playgroud)

解释

这是从总和得出的

(frame.c > 0) * frame.c  # frame.c if positive
Run Code Online (Sandbox Code Playgroud)

(frame.c <= 0) * frame.b  # frame.b if c is not positive
Run Code Online (Sandbox Code Playgroud)

然而

(frame.c <=0 )
Run Code Online (Sandbox Code Playgroud)

相当于

(1 - frame.c > 0)
Run Code Online (Sandbox Code Playgroud)

当结合时你得到

frame['d'] = frame.b + (frame.c > 0) * (frame.c - frame.b)
Run Code Online (Sandbox Code Playgroud)