基于阈值为DataFrame新增列:达标取t1/t2/t3值,否则取t4
问题与解决方案
问题背景
现有如下DataFrame:
| Ref | t1 | t2 | t3 | t4 |
|---|---|---|---|---|
| A | 5 | -3 | 2 | 7 |
| B | -2 | -4 | -1 | 3 |
| C | 1 | 6 | 3 | 9 |
需要新增一列Criteria,规则为:
- 若
t1、t2、t3中任意一列的值≥阈值(示例为5),返回该列的对应值(多列满足时取最先出现的列的值) - 若三列均不满足条件,则返回
t4的值
预期结果:
| Ref | t1 | t2 | t3 | t4 | Criteria |
|---|---|---|---|---|---|
| A | 5 | -3 | 2 | 7 | 5 |
| B | -2 | -4 | -1 | 3 | 3 |
| C | 1 | 6 | 3 | 9 | 6 |
用户尝试的代码仅筛选出满足条件的行,无法实现完整需求:
group = ["t1", "t2", "t3"] df2 = df[(df[group] >= 5).any(axis=1)]
解决方法
方法1:逐列优先级覆盖(高效适合大数据集)
通过numpy.where从后往前依次覆盖,保证先出现的列优先级更高:
import numpy as np import pandas as pd group = ["t1", "t2", "t3"] threshold = 5 # 初始值设为t4 df['Criteria'] = df['t4'] # 从后往前遍历,满足条件则替换为当前列的值 for col in reversed(group): df['Criteria'] = np.where(df[col] >= threshold, df[col], df['Criteria'])
方法2:逐行检查(逻辑直观适合小数据集)
用apply逐行遍历,按顺序判断每列是否符合条件:
threshold = 5 def get_criteria(row): for col in ["t1", "t2", "t3"]: if row[col] >= threshold: return row[col] return row['t4'] df['Criteria'] = df.apply(get_criteria, axis=1)
方法3:掩码+填充(简洁写法)
通过掩码将不满足条件的值转为NaN,再按行向前填充取第一个有效列,最后用t4兜底:
group = ["t1", "t2", "t3"] threshold = 5 # 生成掩码:将小于阈值的元素转为NaN temp_df = df[group].mask(df[group] < threshold) # 按行向前填充取第一个非NaN值,无有效值则用t4填充 df['Criteria'] = temp_df.ffill(axis=1).iloc[:, 0].fillna(df['t4'])
内容的提问来源于stack exchange,提问作者Hotone
相关产品推荐
相关产品推荐

