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

pandas df.apply调用返回字典的函数创建新列失败问题求解

错误原因

原有代码无法运行的核心问题有两点:

  • 连续三次调用df.apply(extract_data, axis=1)会触发三次全表逐行遍历,且直接对返回的字典Series取['a']/['p']/['s']属于按列索引取值,和字典的键不匹配,会触发KeyError。
  • lambda写法传入了不存在的x['a']字段作为参数,extract_data需要接收整行Series作为输入,行数据中无a列,必然运行报错。
单遍apply实现方案

只需要调用一次apply,搭配result_type='expand'参数即可自动将每行返回的字典拆分为独立列,仅需一次遍历即可完成三列赋值:

def extract_info(self):
    def extract_data(row):
        res = {'A': None, 'P': None, 'S': None}
        for info in row['Info']:
            t = info['Type']
            if t in res:
                res[t] = info['Desc']
        return res
    # 自动将返回的字典拆为列,直接拼接回原表
    info_cols = self.df.apply(extract_data, axis=1, result_type='expand')
    self.df = pd.concat([self.df, info_cols], axis=1)
    return self
高性能优化方案(大数据量优先选)

apply本质是Python层逐行循环,数据量较大时性能较差,可以用pandas原生的矢量化方法实现,性能比apply高5~10倍:

def extract_info(self):
    # 炸开Info列的列表为单条记录,再把字典拆为普通列
    info_long = self.df['Info'].explode().apply(pd.Series)
    # 行透视成宽表,索引和原表对齐
    info_wide = info_long.pivot(
        index=info_long.index,
        columns='Type',
        values='Desc'
    )
    # 拼接回原DataFrame
    self.df = pd.concat([self.df, info_wide], axis=1)
    return self

该方案没有手写Python层循环,核心逻辑由pandas C后端实现,数据量越大性能优势越明显,同时不需要手动维护Type和列名的映射关系,后续新增Type类型也能自动生成对应列。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 01:21:34