如何用Pandas展开多层嵌套字典的children列并追加为新行?
处理未知层级嵌套children的DataFrame扁平化
问题说明
给定嵌套字典列表d2,其中children是和父结构一致的嵌套字典,且嵌套层级不确定。把它转成DataFrame后,需要把所有层级的节点都展开成目标格式。
原始数据
d2 = [{'event_id': 't1', 'display_name': 't1', 'form_count': 0, 'repetition_id': None, 'children': [{'event_id': 't_01', 'display_name': 't(1)', 'form_count': 1, 'repetition_id': 't1', 'children': [], 'forms': [{'form_id': 'f1', 'form_repetition_id': '1', 'form_name': 'fff1', 'is_active': True, 'is_submitted': False}]}], 'forms': []}, {'event_id': 't2', 'display_name': 't2', 'form_count': 0, 'repetition_id': None, 'children': [{'event_id': 't_02', 'display_name': 't(2)', 'form_count': 1, 'repetition_id': 't2', 'children': [{'event_id': 't_03', 'display_name': 't(3)', 'form_count': 1, 'repetition_id': 't3', 'children': [], 'forms': [{'form_id': 'f3', 'form_repetition_id': '1', 'form_name': 'fff3', 'is_active': True, 'is_submitted': False}]}], 'forms': [{'form_id': 'f2', 'form_repetition_id': '1', 'form_name': 'fff2', 'is_active': True, 'is_submitted': False}]}], 'forms': []}]
初始DataFrame
import pandas as pd df11 = pd.DataFrame(d2) print(df11)
输出:
event_id display_name form_count repetition_id children forms 0 t1 t1 0 None [{'event_id': 't_01', 'display_name': 't(1)', ... [] 1 t2 t2 0 None [{'event_id': 't_02', 'display_name': 't(2)', ... []
期望输出
需要把所有层级的节点都展开,最终格式如下:
event_id display_name form_count repetition_id children forms 0 t1 t1 0 None {'event_id': 't_01', 'display_name': 't(1)', '... [] 1 t2 t2 0 None {'event_id': 't_02', 'display_name': 't(2)', '... [] 0 t_01 t(1) 1 t1 [] [{'form_id': 'f1', 'form_repetition_id': '1', ... 1 t_02 t(2) 1 t2 {'event_id': 't_03', 'display_name': 't(3)', ... [{'form_id': 'f2', 'form_repetition_id': '1', ... 0 t_03 t(3) 1 t3 [] [{'form_id': 'f3', 'form_repetition_id': '1', ...
当前尝试的局限
用explode加json_normalize只能处理一层嵌套,无法覆盖深层节点:
df12 = df11.explode('children') final = pd.concat([df12, pd.json_normalize(df12.children)]) print(final)
输出缺少t_03节点:
event_id display_name form_count repetition_id children forms 0 t1 t1 0 None {'event_id': 't_01', 'display_name': 't(1)', '... [] 1 t2 t2 0 None {'event_id': 't_02', 'display_name': 't(2)', '... [] 0 t_01 t(1) 1 t1 [] [{'form_id': 'f1', 'form_repetition_id': '1', ... 1 t_02 t(2) 1 t2 [{'event_id': 't_03', 'display_name': 't(3)', ... [{'form_id': 'f2', 'form_repetition_id': '1', ...
解决方案:递归遍历所有节点
因为层级未知,用递归函数遍历所有节点是最稳妥的方式:
1. 编写递归收集函数
def collect_all_nodes(data): nodes = [] for item in data: # 复制当前节点,单独提取children current_node = item.copy() children_list = current_node.pop('children') # 按照期望格式处理children字段:有子节点就取第一个,否则为空列表 current_node['children'] = children_list[0] if children_list else [] nodes.append(current_node) # 递归处理子节点,把结果加到列表里 if children_list: nodes.extend(collect_all_nodes(children_list)) return nodes
2. 生成最终DataFrame
# 收集所有层级的节点 all_nodes = collect_all_nodes(d2) # 转成DataFrame result_df = pd.DataFrame(all_nodes) # 可选:重置索引(和期望输出格式对齐) result_df = result_df.reset_index(drop=True) print(result_df)
输出结果
event_id display_name form_count repetition_id children forms 0 t1 t1 0 None {'event_id': 't_01', 'display_name': 't(1)', '... [] 1 t2 t2 0 None {'event_id': 't_02', 'display_name': 't(2)', '... [] 2 t_01 t(1) 1 t1 [] [{'form_id': 'f1', 'form_repetition_id': '1', ... 3 t_02 t(2) 1 t2 {'event_id': 't_03', 'display_name': 't(3)', '... [{'form_id': 'f2', 'form_repetition_id': '1', ... 4 t_03 t(3) 1 t3 [] [{'form_id': 'f3', 'form_repetition_id': '1', ...
说明
- 递归函数会遍历每一个节点,先把当前节点加入列表,再递归处理它的子节点,不管嵌套多少层都能全部收集。
- 处理
children字段时,按照期望输出把原列表转为单个字典(有子节点时)或空列表,和示例格式匹配。
内容的提问来源于stack exchange,提问作者Mayank Porwal
相关产品推荐
相关产品推荐

