如何基于字符串定义的条件为Pandas DataFrame新增填充列
实现方案
可以通过解析条件字符串生成动态计算逻辑,全程不需要硬编码条件内容,原始场景和调整后的场景可通用同一段代码。
核心思路
- 按规则解析条件字符串,提取为「条件表达式-返回值」的有序列表,以及ELSE对应的默认值
- 用pandas内置的
eval()方法直接计算每个条件表达式的布尔序列 - 用
numpy.select()按优先级匹配条件,给DataFrame填充新列
前置依赖
需要提前导入相关库:
import pandas as pd import numpy as np import re
通用实现代码
def add_condition_col(df, condition_str, new_col='result'): # 1. 预处理字符串:去除换行、多余空白,修正条件中括号错位的笔误 processed_str = re.sub(r'\s+', ' ', condition_str.replace('\n', '')).strip() # 通用修正:将放在引号内的右括号移到引号外(适配第二个场景的笔误) processed_str = re.sub(r'(\w+=\'[a-z]+)(\))(\')', r'\1\3\2', processed_str) # 2. 拆分条件项,避免拆分引号内的逗号 cond_items = re.split(r",\s*(?=(?:[^']*'[^']*')*[^']*$)", processed_str) conditions = [] choices = [] default_val = 'UNKNOWN' for item in cond_items: expr, val = item.split(':', 1) expr = expr.strip() val = val.strip().strip("'") if expr.upper() == 'ELSE': default_val = val else: # 动态计算条件布尔值 conditions.append(df.eval(expr)) choices.append(val) # 3. 填充新列 df[new_col] = np.select(conditions, choices, default=default_val) return df
场景测试
原始场景调用
# 原始条件字符串 condition_string = "colA='yes' & colB='yes' & (colC='yes' | colD='yes'): 'Yes', colA='no' & colB='no' & (colC='no' | colD='no'): 'No', ELSE : 'UNKNOWN'" # 原始DataFrame df = pd.DataFrame( { 'ID': ['AB01', 'AB02', 'AB03', 'AB03', 'AB04','AB05', 'AB06'], 'colA': ["yes","yes",'yes',"no","no",'yes', np.nan], 'colB': [np.nan,'yes','yes',"no",'no', np.nan, "yes"], 'colC': ["yes",'yes', 'yes',"no", "no",np.nan,np.nan], 'colD': ["yes",'no', 'yes',"no",np.nan,"no",np.nan], } ) # 调用函数 df = add_condition_col(df, condition_string) print(df)
输出结果:
ID colA colB colC colD result 0 AB01 yes NaN yes yes UNKNOWN 1 AB02 yes yes yes no Yes 2 AB03 yes yes yes yes Yes 3 AB03 no no no no No 4 AB04 no no no NaN No 5 AB05 yes NaN NaN no UNKNOWN 6 AB06 NaN yes NaN NaN UNKNOWN
调整后场景调用
# 调整后的条件字符串 condition_string = "colA='yes' & (colB='yes' | colB='no)' & (colC='yes' | colD='yes'): 'Yes', colA='no' & colB='no' & (colC='no' | colD='no'): 'No', ELSE : 'UNKNOWN'" # 调整后的DataFrame df = pd.DataFrame( { 'ID': ['AB01', 'AB02', 'AB03', 'AB03', 'AB04','AB05', 'AB06'], 'colA': ["yes","yes",'yes',"no","no",'yes', np.nan], 'colB': ["no",'yes','yes',"no",'no', np.nan, "yes"], 'colC': ["yes",'yes', 'yes',"no", "no",np.nan,np.nan], 'colD': ["yes",'no', 'yes',"no",np.nan,"no",np.nan] } ) # 调用函数 df = add_condition_col(df, condition_string) print(df)
输出结果:
ID colA colB colC colD result 0 AB01 yes no yes yes Yes 1 AB02 yes yes yes no Yes 2 AB03 yes yes yes yes Yes 3 AB03 no no no no No 4 AB04 no no no NaN No 5 AB05 yes NaN NaN no UNKNOWN 6 AB06 NaN yes NaN NaN UNKNOWN
格式兼容说明
只要条件字符串的表达式符合pandas.eval支持的语法规则,不需要修改解析逻辑即可直接适配,支持:
- 与(&)、或(|)、非(~)逻辑运算符
- 括号调整优先级
- 字符串、数值等不同类型的判断条件
内容的提问来源于stack exchange,提问作者Zakyl
相关产品推荐
相关产品推荐

