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

将DataFrame列中字典展开为新列:求高效替代方案

高效展开DataFrame中字典列的实现方案

问题背景

现有如下包含字典元素的DataFrame:

import pandas as pd

data = {'player1':[{'y': -3.52297115326,
  'x': -8.8917736553,
  'group_name': 'home team',
  'track_id': 2},{'y': -3.48258808681,
  'x': -8.85969284603,
  'group_name': 'home team',
  'track_id': 2},{'y': -3.45125194958,
  'x': -8.83364221028,
  'group_name': 'home team',
  'track_id': 2}],
     'player2':[{'y': -3.52297115326,
  'x': -8.8917736553,
  'group_name': 'home team',
  'track_id': 2},{'y': -3.48258808681,
  'x': -8.85969284603,
  'group_name': 'home team',
  'track_id': 2},{'y': -3.45125194958,
  'x': -8.83364221028,
  'group_name': 'home team',
  'track_id': 2}]}
df = pd.DataFrame(data)

需要将每列的字典展开为独立列,最终输出如下结构:

data2 = {'y': [-3.52291,-3.482588,-3.451252],'x':[-8.891774,-8.859693,-8.833642],'group_name':['home_team','home_team','home_team'],'track_id':[2,2,2],'player2_y': [-3.52291,-3.482588,-3.451252],'player2_x':[-8.891774,-8.859693,-8.833642],'player2_group_name':['home_team','home_team','home_team'],'player2_track_id':[2,2,2]}

df2 = pd.DataFrame(data2)

输出表格预览:

yxgroup_nametrack_idplayer2_yplayer2_xplayer2_group_nameplayer2_track_id
0-3.522910-8.891774home_team2-3.522910-8.891774home_team2
1-3.482588-8.859693home_team2-3.482588-8.859693home_team2
2-3.451252-8.833642home_team2-3.451252-8.833642home_team2

原实现方法逐列apply(pd.Series)+concat,在数据量较大时效率极低:

df = pd.concat([df.drop(['player1'], axis=1), df['player1'].apply(pd.Series)], axis=1)
df = pd.concat([df.drop(['player2'], axis=1), df['player2'].apply(pd.Series)], axis=1)

高效解决方案

方法1:使用pd.json_normalize批量处理(推荐)

json_normalize是pandas针对嵌套字典/JSON数据优化的工具,处理效率远高于apply(pd.Series)。通过循环遍历所有列,对每列字典数据标准化后添加前缀(首列除外),最后一次性合并结果:

# 初始化存储标准化结果的列表
result_dfs = []

for col in df.columns:
    # 标准化当前列的字典数据
    normalized_df = pd.json_normalize(df[col])
    # 非首列的字段添加列名前缀,避免列名冲突
    if col != df.columns[0]:
        normalized_df = normalized_df.add_prefix(f"{col}_")
    result_dfs.append(normalized_df)

# 合并所有标准化后的DataFrame
df2 = pd.concat(result_dfs, axis=1)

# 可选:将group_name中的空格替换为下划线,匹配示例输出
df2['group_name'] = df2['group_name'].str.replace(' ', '_')
df2['player2_group_name'] = df2['player2_group_name'].str.replace(' ', '_')

方法2:列表推导式简化代码

逻辑与方法1一致,用列表推导式缩减代码行数:

# 批量生成标准化后的DataFrame列表
normalized_dfs = [
    pd.json_normalize(df[col]).add_prefix(f"{col}_") if col != df.columns[0]
    else pd.json_normalize(df[col])
    for col in df.columns
]

# 合并结果
df2 = pd.concat(normalized_dfs, axis=1)

# 处理group_name的空格
df2 = df2.replace({'group_name': {' ': '_'}, 'player2_group_name': {' ': '_'}})

效率优势说明

  • 原始方法:每次apply(pd.Series)和concat都会生成新的DataFrame并复制数据,中间环节多,数据量大时IO开销极高。
  • 优化方法:json_normalize基于底层优化实现,处理字典数据的速度比apply快一个数量级;批量处理后一次性合并,减少了中间数据复制的次数,大幅提升运行效率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 21:30:47