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

如何将pandas中包含嵌套字典列表的列转换为多行数据?

pandas嵌套字典列表列展开为多行的实现方法

需求说明

我有一个pandas DataFrame,其中一列存储的是嵌套字典组成的列表,示例数据构造代码如下:

import pandas as pd
import numpy as np

df = pd.DataFrame({"Column_1" : [
                                 [{'PID': '03', 'Col_par': [{'PID': '01', 'mace': [{'all': 100, 'd_Loc': 'front'}]}]}],
                                np.nan,
                                [{'PID': '01', 'Col_par': [{'PID': '02', 'mace': [{'all': 100, 'd_Loc': 'driver side'}]}]}],
                                [{'PID': '01', 'Col_par': [{'PID': '11', 'mace': [{'all': 0, 'd_Loc': 'front'}]}, 
                                                        {'PID': '14', 'mace': [{'all': 23, 'd_Loc': 'rear'}]}, 
                                                        {'PID': '06', 'mace': [{'all': 0, 'd_Loc': 'rear'}]}]}, 
                                {'PID': '06', 'Col_par': [{'PID': '11', 'mace': [{'all': 0, 'd_Loc': 'front'}]},
                                                        {'PID': '01', 'mace': [{'all': 0, 'd_Loc': 'front'}]}, 
                                                        {'PID': '14', 'mace': [{'all': 0, 'd_Loc': 'rear'}, 
                                                                                {'all': 0, 'd_Loc': 'front'}]}, 
                                                        {'PID': '10', 'mace': [{'all': 0, 'd_Loc': 'rear'}]}]}, 
                                {'PID': '14', 'Col_par': [{'PID': '11', 'mace': [{'all': 0, 'd_Loc': 'front'}]}, 
                                                        {'PID': '01', 'mace': [{'all': 0, 'd_Loc': 'front'}]}, 
                                                        {'PID': '06', 'mace': [{'all': 25, 'd_Loc': 'rear'}, 
                                                                                {'all': 100, 'd_Loc': 'front'}]}, 
                                                        {'PID': '10', 'mace': [{'all': 100, 'd_Loc': 'rear'}]}]}, 
                                {'PID': '11', 'Col_par': [{'PID': '01', 'mace': [{'all': 100, 'd_Loc': 'front'}]}, 
                                                        {'PID': '14', 'mace': [{'all': 53, 'd_Loc': 'rear'}]}, 
                                                        {'PID': '06', 'mace': [{'all': 0, 'd_Loc': 'rear'}]}]}, 
                                {'PID': '10', 'Col_par': [{'PID': '14', 'mace': [{'all': 0, 'd_Loc': 'rear'}, 
                                                                                {'all': 0, 'd_Loc': 'front'}]}, 
                                                        {'PID': '06', 'mace': [{'all': 0, 'd_Loc': 'rear'}, 
                                                                                {'all': 0, 'd_Loc': 'front'}]}]}],
                                [{'PID': '03', 'Col_par': [{'PID': '01', 'mace': [{'all': 0, 'd_Loc': 'rear'}, 
                                                                                {'all': 0, 'd_Loc': 'front'}]}, 
                                                        {'PID': '06', 'mace': [{'all': 0, 'd_Loc': 'rear'}, 
                                                                                {'all': 0, 'd_Loc': 'front'}]}, 
                                                        {'PID': '09', 'mace': [{'all': 0, 'd_Loc': 'rear'}, 
                                                                                {'all': 0, 'd_Loc': 'front'}]}]}, 
                                {'PID': '06', 'Col_par': [{'PID': '01', 'mace': [{'all': 0, 'd_Loc': 'rear'}, 
                                                                                {'all': 0, 'd_Loc': 'front'}]}, 
                                                        {'PID': '03', 'mace': [{'all': 0, 'd_Loc': 'rear'}, 
                                                                                {'all': 0, 'd_Loc': 'front'}]}, 
                                                        {'PID': '09', 'mace': [{'all': 0, 'd_Loc': 'rear'}, 
                                                                                {'all': 0, 'd_Loc': 'front'}]}]}, 
                                {'PID': '08', 'Col_par': [{'PID': '01', 'mace': [{'all': 100, 'd_Loc': 'rear'}, 
                                                                                {'all': 100, 'd_Loc': 'front'}]}, 
                                                        {'PID': '03', 'mace': [{'all': 100, 'd_Loc': 'rear'}, 
                                                                                {'all': 100, 'd_Loc': 'front'}]}, 
                                                        {'PID': '06', 'mace': [{'all': 100, 'd_Loc': 'rear'}, 
                                                                                {'all': 100, 'd_Loc': 'front'}]}, 
                                                        {'PID': '09', 'mace': [{'all': 100, 'd_Loc': 'rear'}, 
                                                                                {'all': 100, 'd_Loc': 'front'}]}]}, 
                                {'PID': '09', 'Col_par': [{'PID': '01', 'mace': [{'all': 0, 'd_Loc': 'rear'}, 
                                                                                {'all': 0, 'd_Loc': 'front'}]}, 
                                                        {'PID': '03', 'mace': [{'all': 0, 'd_Loc': 'rear'}, 
                                                                                {'all': 0, 'd_Loc': 'front'}]}, 
                                                        {'PID': '06', 'mace': [{'all': 0, 'd_Loc': 'rear'}, 
                                                                                {'all': 0, 'd_Loc': 'front'}]}]}, 
                                {'PID': '01', 'Col_par': [{'PID': '03', 'mace': [{'all': 0, 'd_Loc': 'rear'}, 
                                                                                {'all': 0, 'd_Loc': 'front'}]}, 
                                                        {'PID': '06', 'mace': [{'all': 0, 'd_Loc': 'rear'}, 
                                                                                {'all': 0, 'd_Loc': 'front'}]}, 
                                                        {'PID': '09', 'mace': [{'all': 0, 'd_Loc': 'rear'}, 
                                                                                {'all': 0, 'd_Loc': 'front'}]}]}]],
                   "Key" : [1, 2, 3, 4, 5],
                   "Val_1": [25, 46, 75, 85, 89]})

当前数据预览:

Column_1                                          Key Val_1
0   [{'PID': '03', 'Col_par': [{'PID': '01', 'mace...   1    25
1   NaN                                                 2    46
2   [{'PID': '01', 'Col_par': [{'PID': '02', 'mace...   3    75
3   [{'PID': '01', 'Col_par': [{'PID': '11', 'mace...   4    85
4   [{'PID': '03', 'Col_par': [{'PID': '01', 'mace...   5    89

我需要提取嵌套字典中的对应字段值,将嵌套字典列表结构展开为独立的行,目标输出格式如下:

PID_Val,  Col_par_PID,  PID_mace_all,  PID_d_loc,  Key,  Val1
'03',            '01',           100,    'front',    1,    25
np.nan,        np.nan,        np.nan,     np.nan,    2,    46
'01',            '02',           100,'driver side',  3,    75
'01',            '11',             0,    'front',    4,    85
'01',            '14',            23,     'rear',    4,    85
'01',            '06',             0,     'rear',    4,    85
'06',            '11',             0,    'front',    4,    85
'06',            '01',             0,    'front',    4,    85
'06',            '14',             0,     'rear',    4,    85

  # 其余行以此类推

实现方案

核心思路是通过explode逐层展开嵌套的列表结构,配合json_normalize解析字典字段,全程保留原有行的Key和Val_1字段关联:

# 第一层展开:展开Column_1最外层的列表
df_explode1 = df.explode('Column_1', ignore_index=False)

# 解析第一层字典,提取PID_Val字段,保留原有索引关联其他字段
df_level1 = pd.json_normalize(df_explode1['Column_1']).set_index(df_explode1.index)
df_level1 = df_level1.rename(columns={'PID': 'PID_Val'})

# 合并原表的Key、Val_1字段
df_merged1 = pd.concat([df_level1, df[['Key', 'Val_1']]], axis=1)

# 第二层展开:展开Col_par列表
df_explode2 = df_merged1.explode('Col_par', ignore_index=False)

# 解析第二层字典,提取Col_par_PID字段
df_level2 = pd.json_normalize(df_explode2['Col_par']).set_index(df_explode2.index)
df_level2 = df_level2.rename(columns={'PID': 'Col_par_PID'})
df_merged2 = pd.concat([df_explode2.drop('Col_par', axis=1), df_level2], axis=1)

# 第三层展开:展开mace列表
df_explode3 = df_merged2.explode('mace', ignore_index=False)

# 解析第三层字典,提取对应字段并改名
df_level3 = pd.json_normalize(df_explode3['mace']).set_index(df_explode3.index)
df_level3 = df_level3.rename(columns={'all': 'PID_mace_all', 'd_Loc': 'PID_d_loc'})

# 合并得到最终结果,按目标顺序重排列
final_df = pd.concat([df_explode3.drop('mace', axis=1), df_level3], axis=1)
final_df = final_df[['PID_Val', 'Col_par_PID', 'PID_mace_all', 'PID_d_loc', 'Key', 'Val_1']].reset_index(drop=True)

运行后输出final_df即可得到符合要求的展开结果,原NaN行也会保留所有字段为NaN值。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 17:39:03