如何在不使用eval()的情况下基于字符串计算式为DataFrame新增列
问题:避免使用eval(),基于字符串计算式生成Pandas新列
给定如下Pandas DataFrame:
import pandas as pd df = pd.DataFrame({'1': [10, 20, 30], 2: [100, 200, 300]}) # 输出结果: # 1 2 # 0 10 100 # 1 20 200 # 2 30 300
需要基于字符串形式的计算式生成新列,计算式示例:
calc = '{1}+{2}'
之前尝试通过apply+lambda结合eval()实现,但希望避免使用eval(),寻求替代方案。
解决方案1:解析计算式,手动执行向量化运算
通过正则表达式提取计算式中的列名和运算符,直接利用Pandas的向量化操作完成计算,全程无需eval():
import re import pandas as pd df = pd.DataFrame({'1': [10, 20, 30], 2: [100, 200, 300]}) calc = '{1}+{2}' # 提取计算式中的列名 cols = re.findall(r'\{(\w+)\}', calc) # 提取运算符(适用于二元运算场景) operator = re.sub(r'\{.*?\}', '', calc).strip() # 根据运算符执行对应计算 if operator == '+': df['new_col'] = df[cols[0]] + df[cols[1]] elif operator == '-': df['new_col'] = df[cols[0]] - df[cols[1]] elif operator == '*': df['new_col'] = df[cols[0]] * df[cols[1]] elif operator == '/': df['new_col'] = df[cols[0]] / df[cols[1]] # 可根据需要扩展更多运算符(如//、**等)
执行后df将新增new_col列,值为[110, 220, 330],完全符合计算式要求。
解决方案2:使用Pandas内置的eval()(安全替代方案)
如果只是担心内置eval()的安全性,可以使用Pandas专属的df.eval()方法——它仅允许访问DataFrame的列和有限的合法表达式,不会执行任意Python代码,安全性更高,同时代码更简洁:
import pandas as pd df = pd.DataFrame({'1': [10, 20, 30], 2: [100, 200, 300]}) calc = '{1}+{2}' # 将计算式中的{}替换为列名 calc_pandas = calc.replace('{', '').replace('}', '') # 使用df.eval()生成新列 df['new_col'] = df.eval(calc_pandas)
这种方法既满足了避免危险的内置eval()的需求,又能快速实现功能,适合复杂一点的计算式场景。
内容的提问来源于stack exchange,提问作者dnnshssm
相关产品推荐
相关产品推荐

