pandas基于多列非空值优先级规则新建行最终状态列的实现方法
实现步骤与代码
核心逻辑拆解
- 逐行扫描三个状态列,定位位置最靠后的非空取值(列顺序固定为status_1 < status_2 < status_3,即从左到右位置越靠右优先级越高)
- 按照固定映射关系将抓取的原始状态转换为最终状态:
c_approved→approvedc_rejected→rejecteda_approved→reviseda_rejected→rejected
高性能向量化实现(推荐)
全部采用pandas内置向量化操作,无逐行Python循环,处理大数据集时效率远高于自定义循环写法。
- 导入依赖并构造测试样例:
import pandas as pd import numpy as np # 构造测试数据集 df = pd.DataFrame({ "status_1": ["c_approved", "a_rejected", np.nan, "a_approved", np.nan], "status_2": [np.nan, "c_rejected", "a_approved", np.nan, np.nan], "status_3": [np.nan, np.nan, "c_approved", "a_rejected", np.nan] })
- 逐行抓取最靠后的非空状态:
利用ffill(axis=1)横向向前填充的特性,填充后每行最右侧列的值,即为该行从左到右最后出现的非空取值,完全匹配业务规则:
target_status = df[["status_1", "status_2", "status_3"]].ffill(axis=1).iloc[:, -1]
- 定义映射规则生成最终状态列:
status_map = { "c_approved": "approved", "c_rejected": "rejected", "a_approved": "revised", "a_rejected": "rejected" } df["final_status"] = target_status.map(status_map)
注意:若某一行三个状态列全为缺失值,映射结果会为NaN,可根据业务需求用
df["final_status"] = df["final_status"].fillna("unknown")补充默认值。
运行后输出的结果样例:
| status_1 | status_2 | status_3 | final_status |
|---|---|---|---|
| c_approved | NaN | NaN | approved |
| a_rejected | c_rejected | NaN | rejected |
| NaN | a_approved | c_approved | approved |
| a_approved | NaN | a_rejected | rejected |
| NaN | NaN | NaN | NaN |
备选直观写法(适合小数据集)
如果更偏好逐行逻辑的可读性,可使用apply实现,性能稍低但逻辑更直白:
status_map = { "c_approved": "approved", "c_rejected": "rejected", "a_approved": "revised", "a_rejected": "rejected" } def calculate_final_status(row): # 从最靠右的列向前遍历,取第一个找到的非空值 for col in ["status_3", "status_2", "status_1"]: current_val = row[col] if pd.notna(current_val): return status_map[current_val] # 三列全空时返回默认值 return "unknown" df["final_status"] = df.apply(calculate_final_status, axis=1)
内容的提问来源于stack exchange,提问作者nomnom3214
相关产品推荐
相关产品推荐

