如何将Excel规则表转为Python代码实现CSV数据列转换?
动态规则实现CSV列转换问题
我有一个类似Case语句的Excel配置文件,表格结构如下:
| Condition | Operator | Comparison | Output |
|---|---|---|---|
| Country | == | 'US' | '1' |
| Country | == | 'UK' | '2' |
规则说明:
Condition对应CSV数据中的列名- 当条件匹配时返回对应的
Output - Excel支持动态添加规则,脚本需要自动应用新增规则完成CSV列转换
我尝试用eval()和getattr()实现遍历规则转换,但都没成功,以下是我的尝试代码:
尝试1:使用eval()的代码
import pandas as pd df = pd.read_csv('DummyData.csv') transform = pd.read_excel("t.xlsx") def transform_data(row): for i in range(len(transform)): condition = transform.iloc[i,0] operator = transform.iloc[i,1] comparison = transform.iloc[i,2] output = transform.iloc[i,3] if eval(f"row['{condition}']{operator}"): return output return None df["Country"] = df.apply(transform_data(1), axis = 1)
尝试2:整合Comparison到Operator列用getattr()的代码
import pandas as pd import operator df = pd.read_csv('DummyData.csv') transform = pd.read_excel("t.xlsx") def transform_data(row): for i in range(len(transform)): condition = transform.iloc[i,0] operator_str = transform.iloc[i,1] output = transform.iloc[i,2] operator_func = getattr(operator, operator_str) if operator_func(row[condition],output): return output return None df["Country"] = df.apply(transform_data, axis = 1)
问题分析与解决方案
原代码问题点
eval()版本问题:
- 字符串拼接不完整:缺少
comparison值,条件表达式未闭合 return None位置错误:放在循环内部,第一次不匹配就直接返回,不会遍历后续规则apply调用错误:传入了函数执行结果而非函数对象
- 字符串拼接不完整:缺少
getattr()版本问题:
- Excel列映射错误:混淆了
Comparison和Output的位置 - 运算符名不匹配:
operator模块用eq而非==,需要做符号到方法名的映射
- Excel列映射错误:混淆了
修正后的代码方案
方案1:安全替代eval的实现(推荐)
避免eval的安全风险,用运算符映射表实现:
import pandas as pd import operator # 运算符到operator方法的映射表 op_map = { '==': operator.eq, '!=': operator.ne, '>': operator.gt, '<': operator.lt, '>=': operator.ge, '<=': operator.le } df = pd.read_csv('DummyData.csv') transform_rules = pd.read_excel("t.xlsx") def apply_rules(row): # 遍历所有规则,返回第一个匹配的Output for _, rule in transform_rules.iterrows(): col_name = rule['Condition'] op_func = op_map[rule['Operator']] # 去除Excel中字符串的单引号 compare_val = rule['Comparison'].strip("'") output_val = rule['Output'].strip("'") if op_func(row[col_name], compare_val): return output_val # 无匹配规则时返回原列值 return row[col_name] # 生成新列避免覆盖原数据 df['Country_Code'] = df.apply(apply_rules, axis=1) df.to_csv('TransformedData.csv', index=False)
方案2:修复后的eval版本(仅作参考)
import pandas as pd df = pd.read_csv('DummyData.csv') transform_rules = pd.read_excel("t.xlsx") def apply_rules(row): for _, rule in transform_rules.iterrows(): condition = rule['Condition'] operator = rule['Operator'] comparison = rule['Comparison'] output = rule['Output'] # 完整拼接条件表达式 if eval(f"row['{condition}'] {operator} {comparison}"): return output.strip("'") return row[condition] df['Country_Code'] = df.apply(apply_rules, axis=1) df.to_csv('TransformedData.csv', index=False)
关键优化点
- 用
iterrows()遍历规则,比iloc更直观易读 - 处理Excel中带单引号的字符串值,避免类型不匹配
- 修正循环返回逻辑,确保遍历所有规则后才返回默认值
- 运算符映射表解决
operator模块方法名与Excel符号不匹配的问题
内容的提问来源于stack exchange,提问作者Matt Caruso
相关产品推荐
相关产品推荐

