如何将任意深度嵌套字典转换为指定格式的Pandas DataFrame?
解决方案:递归收集完整路径记录转DataFrame
针对你遇到的嵌套字典转DataFrame时无法追踪前序键、json.normalize生成带点列名的问题,核心思路是递归遍历字典时完整记录每条路径上的列名和对应值,最终将所有路径整理成结构化的行记录,再转换为DataFrame。
实现步骤
- 编写递归函数,遍历嵌套字典时维护当前路径的列值对(
current_record); - 遇到子字典时,将当前列名和取值加入记录,继续递归处理子结构;
- 遇到非字典的最终值时,将完整记录存入结果列表;
- 将结果列表直接转换为DataFrame,自动补全缺失列的
NaN。
完整代码
import pandas as pd # 初始化结果记录列表 records = [] def flatten_nested_dict(d, current_record=None): if current_record is None: current_record = {} # 遍历当前层级的列名与对应数据 for col_name, col_data in d.items(): if isinstance(col_data, dict): # 若当前列数据是字典,说明是下一级列的取值集合 for col_value, sub_struct in col_data.items(): # 复制当前记录,避免递归时修改原数据 new_record = current_record.copy() new_record[col_name] = col_value # 递归处理子结构 flatten_nested_dict(sub_struct, new_record) else: # 若当前列数据是非字典,说明是最终值,保存完整记录 final_record = current_record.copy() final_record[col_name] = col_data records.append(final_record) # 处理你的嵌套字典示例 test = { 'column-gender': { 'male': { 'column-country' : { 'FRENCH': { 'column-class': [0,1] }, ('SPAIN','ITALY') : { 'column-married' : { 'YES': { 'column-class' : [0,1] }, 'NO' : { 'column-class' : 2 } } } } }, 'female': { 'column-country' : { ('FRENCH', 'SPAIN') : { 'column-class' : [[1,2],'#'] }, 'REST-OF-VALUES': { 'column-married' : '*' } } } } } flatten_nested_dict(test) # 转换为DataFrame并调整列顺序(可选) df = pd.DataFrame(records) df = df[['column-gender', 'column-country', 'column-married', 'column-class']] print(df)
输出结果
column-gender column-country column-married column-class 0 male FRENCH NaN [0, 1] 1 male (SPAIN, ITALY) YES [0, 1] 2 male (SPAIN, ITALY) NO 2 3 female (FRENCH, SPAIN) NaN [[1, 2], #] 4 female REST-OF-VALUES * NaN
关键说明
- 递归函数通过
current_record传递当前路径的所有列值对,完美解决了前序键追踪的问题; - 自动处理元组键、列表/字符串/数字等多种类型的最终值;
- 生成的DataFrame列名直接对应原字典中的
column-xxx,不会出现json.normalize的点连接列名问题; - 缺失的列会自动填充
NaN,保证数据结构的一致性。
内容的提问来源于stack exchange,提问作者Tonino Fernandez
相关产品推荐
相关产品推荐

