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

如何在未知列名的Pandas DataFrame中用f-string模板创建新列

解决Pandas动态模板生成新列的向量化方案

核心问题

需要基于未知列名和动态模板生成新列,但pd.eval不支持f-string语法,迭代行或普通apply又不够优雅高效。

最优方案:将f-string模板转换为pd.eval兼容表达式

pd.eval支持列名与字符串的向量化拼接,我们可以把用户提供的f-string模板转换为pd.eval能识别的表达式,实现高效的向量化操作。

步骤1:编写模板转换函数

这个函数会自动将f-string格式的模板转换成pd.eval支持的语法:

import re

def fstring_to_eval_expr(template):
    # 移除f前缀和首尾引号,提取模板核心内容
    content = template.strip().lstrip('f').strip('"').strip("'")
    # 分割模板中的列引用和固定字符串部分
    parts = re.split(r'(\{[^}]+\})', content)
    expr_parts = []
    for part in parts:
        if part.startswith('{') and part.endswith('}'):
            # 处理列引用,比如{col2}转为col2
            col_name = part.strip('{}')
            expr_parts.append(col_name)
        else:
            # 处理固定字符串,用单引号包裹
            if part:
                expr_parts.append(repr(part))
    # 用+拼接所有部分,生成eval可执行的表达式
    return ' + '.join(expr_parts)

步骤2:生成新列

以示例DataFrame为例:

import pandas as pd

# 示例DataFrame
df = pd.DataFrame({
    'col1': ['abc', 'ghi'],
    'col2': ['def', 'jkl']
})

# 用户提供的f-string模板
template = 'f"{col2}_x"'

# 转换模板为eval表达式
eval_expr = fstring_to_eval_expr(template)
# eval_expr结果:'col2 + "_x"'

# 向量化生成新列
df['new_col'] = df.eval(eval_expr)

执行后得到的结果:

col1 col2 new_col
0    abc  def  def_x
1    ghi  jkl  jkl_x

支持复杂模板

如果模板包含多列拼接或字符串方法,转换函数也能处理:

  • 多列拼接模板:template = 'f"{col1}-{col2}_suffix"'
    转换后表达式:col1 + "-" + col2 + "_suffix"
  • 带字符串方法的模板:修改转换函数支持方法调用:
    def fstring_to_eval_expr(template):
        content = template.strip().lstrip('f').strip('"').strip("'")
        pattern = re.compile(r'\{([^}]+)\}')
        
        def replace_match(match):
            inner = match.group(1)
            # 处理列的字符串方法,比如col1.upper()转为col1.str.upper()
            if '.' in inner:
                col, method = inner.split('.', 1)
                return f"{col}.str.{method}"
            return inner
        
        replaced = pattern.sub(replace_match, content)
        parts = re.split(r'([a-zA-Z0-9_.]+)', replaced)
        expr_parts = []
        for part in parts:
            if part and not re.match(r'[a-zA-Z0-9_.]+', part):
                expr_parts.append(repr(part))
            elif part:
                expr_parts.append(part)
        return ' + '.join(expr_parts)
    
    使用模板template = 'f"{col1.upper()}_{col2}"',会生成表达式col1.str.upper() + "_" + col2,最终得到ABC_def、GHI_jkl的结果。

备选方案:小数据集用apply

如果数据集很小,或者模板逻辑过于复杂(比如包含条件判断),可以直接用apply:

df['new_col'] = df.apply(lambda row: template.strip().lstrip('f').format(**row), axis=1)

注意:这个方法是逐行处理,大数据集下效率远低于向量化的eval方案。

内容的提问来源于stack exchange,提问作者j0hn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 10:52:20