如何在pandas中结合.assign与.where实现类numpy.where的三元逻辑
解决Pandas条件分支赋值并添加新列的问题
问题背景
给定如下Pandas DataFrame:
import pandas as pd values = [("a", 1), ("b", 2), ("c", 3), ("d", 4), ("a", 4), ("b", 6), ("c", 7), ("d", 8)] df = pd.DataFrame(values, columns=["name", "value"])
对应的表格:
| name | value |
|---|---|
| a | 1 |
| b | 2 |
| c | 3 |
| d | 4 |
| a | 4 |
| b | 6 |
| c | 7 |
| d | 8 |
需要满足以下要求:
- 添加名为
kpi的新列 - 在函数链式调用中使用
.assign方法 - 不使用
numpy - 不使用
.apply(避免循环低效) - 不使用
.query(缺少开发便利性) - 条件规则:
若(name属于["a","b"] 且 value是偶数),则kpi = value / 5 * 100,否则kpi = value / 2
最终目标表格:
| name | value | kpi |
|---|---|---|
| a | 1 | 0.5 |
| b | 2 | 40 |
| c | 3 | 1.5 |
| d | 4 | 2 |
| a | 4 | 80 |
| b | 6 | 120 |
| c | 7 | 3.5 |
| d | 8 | 4 |
疑问:Pandas的.where()是否支持设置else分支?
解答
.where()的else分支说明
Pandas 的 .where() 方法原生就支持设置 else 分支,语法是 Series.where(condition, other):当条件为 True 时保留原序列的值,条件为 False 时就用 other 参数指定的值/计算逻辑来替换。
满足所有要求的实现代码
直接用 .assign 链式调用结合 .where() 就能搞定,完全符合你的限制条件:
result_df = df.assign( kpi=lambda x: (x["value"] / 5 * 100).where( (x["name"].isin(["a", "b"])) & (x["value"] % 2 == 0), other=x["value"] / 2 ) )
代码逻辑拆解
- 条件判断:
(x["name"].isin(["a", "b"])) & (x["value"] % 2 == 0)精准对应你要求的触发规则 .where()分支逻辑:- 条件成立时,执行
value /5 *100计算kpi - 条件不成立时,自动使用
other参数里的value /2作为kpi值
- 条件成立时,执行
- 链式调用:
.assign方法完美适配链式调用场景,不需要额外修改原DataFrame(也可以直接覆盖原df)
运行这段代码后,输出的结果和你给出的目标表格完全一致。
内容的提问来源于stack exchange,提问作者Vega
相关产品推荐
相关产品推荐

