Pandas中assign结合lambda时Series条件判断报错的解决方法
问题原因与解决方法
为什么会报错?
你在assign的lambda里,参数x是整个DataFrame对象,不是单独一行数据,所以x['str']返回的是整个str列的Series,不是单个元素。直接用if (x['str'] < 1105)相当于要判断一整列布尔值的真假——Pandas根本不知道你要的是“任意一个元素满足就行”还是“所有元素都得满足”,所以抛出这个歧义错误。
正确实现方式
推荐用矢量化操作(Pandas最优实践,速度远快于逐行处理):
方法1:用numpy.where(最通用)
直接在assign里调用np.where,按条件选择对应列的值:
import numpy as np import pandas as pd # 构造DataFrame的代码不变 df = pd.DataFrame({'str': [700,705,710,715,720,1095,1100,1105,1110,1115,1120,1125,1130,1135,1205,1210,1215,1220,1225,1230,1235,1240,1245,1250,1255], 'P': [0.075,0.075,0.075,0.075,0.075,17.95,19.75,21.85,24.25,26.55,29.2,31.9,35.05,37.7,98.6,102.15,108.5,113.5,118.4,123.55,127.3,132.7,138.7,142.7,148.35], 'C': [407.8,403.65,398.3,391.65,387.8,30.05,26.65,23.7,21.35,19.65,16.05,14.3,11.95,9.95,0.475,0,0.525,0,0.2,0.175,0.15,0.375,0.125,0.075,0.175]}) # 正确的条件赋值 df = df.assign(ot=lambda x: np.where(x['str'] < 1105, x['P'], x['C'])) print(df)
方法2:用Pandas的Series.where
逻辑是:当条件满足时保留当前Series的值,否则替换为另一列的值:
df = df.assign(ot=lambda x: x['P'].where(x['str'] < 1105, x['C']))
方法3:逐行处理(不推荐,大数据量慢)
如果非要逐行判断,用apply并指定axis=1,此时lambda的参数会是单独一行:
df = df.assign(ot=lambda x: x.apply(lambda row: row['P'] if row['str'] < 1105 else row['C'], axis=1))
总结
Pandas的assign方法中,lambda接收的是整个DataFrame,不是单一行。做条件赋值时优先用矢量化工具,避免用Python原生if-else直接判断Series,既高效又符合Pandas的设计逻辑。
内容的提问来源于stack exchange,提问作者JeeyCi
相关产品推荐
相关产品推荐

