You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Excel规则表转为Python代码实现CSV数据列转换?

动态规则实现CSV列转换问题

我有一个类似Case语句的Excel配置文件,表格结构如下:

ConditionOperatorComparisonOutput
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)

问题分析与解决方案

原代码问题点

  1. eval()版本问题:

    • 字符串拼接不完整:缺少comparison值,条件表达式未闭合
    • return None位置错误:放在循环内部,第一次不匹配就直接返回,不会遍历后续规则
    • apply调用错误:传入了函数执行结果而非函数对象
  2. getattr()版本问题:

    • Excel列映射错误:混淆了Comparison和Output的位置
    • 运算符名不匹配:operator模块用eq而非==,需要做符号到方法名的映射

修正后的代码方案

方案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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 07:47:25