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

Posted

技术标签:

【中文标题】在 Pandas 数据框中的不同列上使用 lambda if 条件【英文标题】:Using lambda if condition on different columns in Pandas dataframe 【发布时间】:2016-09-23 09:48:46 【问题描述】:

我有简单的数据框:

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

例如:

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

然后我想创建列“d”,如果 c 为正,则包含来自“c”的值。来自“b”的其他值。

我正在尝试:

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

但是得到“ValueError:('一个Series的真值是模棱两可的。使用a.empty, a.bool(), a.item(), a.any() or a.all().', '发生在索引 a')

我试图谷歌如何解决这个问题,但没有成功。请问有什么建议吗?

【问题讨论】:

lambda x: ... 因为它需要一个不用于逻辑的参数x..... frame['c']>0 在列 c 中生成一系列大于 0 的值,然后尝试使用它的布尔值而不是 x['c']>0 将特定单元格处的值与0 并返回一个布尔值。 【参考方案1】:

这就是你想要的吗?

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

【讨论】:

【参考方案2】:

解决方案

使用矢量化方法

frame['d'] = frame.b + (frame.c > 0) * (frame.c - frame.b)

说明

这是从总和得出的

(frame.c > 0) * frame.c  # frame.c if positive

加号

(frame.c <= 0) * frame.b  # frame.b if c is not positive

然而

(frame.c <=0 )

等价于

(1 - frame.c > 0)

合并后得到

frame['d'] = frame.b + (frame.c > 0) * (frame.c - frame.b)

【讨论】:

以上是关于在 Pandas 数据框中的不同列上使用 lambda if 条件的主要内容,如果未能解决你的问题,请参考以下文章

在 Pandas 数据框中找到最小值并在新列上添加标签

使用 Pandas 将数据框中的 Python 对象列转换为没有日期的时间

熊猫合并:合并同一列上的两个数据框,但保留不同的列

熊猫数据框列上的子字符串

.diff() 函数仅在 pandas 数据框中返回 NaN 值

使用 pandas 连接两个数据框中的不同列(并附加相似的列)