如何将含层级列的Pandas DataFrame转换为嵌套列表对象?
将带层级指示列的DataFrame转为嵌套数组的简洁方法
问题描述
现有如下包含层级分组列的DataFrame,其中group_*系列列表示数据的层级关系:第2、3行是第1行的子项,第4行是第2行的子项,最后一行无任何子项。需要将其转换为指定格式的嵌套数组。
DataFrame定义代码:
from pandas import DataFrame df = DataFrame( { "var1": [1, 2, 3, 4, 9], "var2": [5, 6, 7, 8, 9], "group_1": [1, 1, 1, 1, 2], "group_2": [None, 1, 2, 1, None], "group_3": [None, None, None, 1, None], } )
DataFrame内容:
| var1 | var2 | group_1 | group_2 | group_3 |
|---|---|---|---|---|
| 1 | 5 | 1 | NaN | NaN |
| 2 | 6 | 1 | 1.0 | NaN |
| 3 | 7 | 1 | 2.0 | NaN |
| 4 | 8 | 1 | 1.0 | 1.0 |
| 9 | 9 | 2 | NaN | NaN |
期望输出格式:
[ { "var1": 1, "var2": 5, "children": [ { "var1": 2, "var2": 6, "children": [{"var1": 4, "var2": 8, "children": []}], }, {"var1": 3, "var2": 7, "children": []}, ], }, {"var1": 9, "var2": 9, "children": []}, ]
解决方案
可以通过构建层级路径+节点映射的方式实现,步骤简洁且逻辑清晰:
import pandas as pd # 定义原始DataFrame df = pd.DataFrame( { "var1": [1, 2, 3, 4, 9], "var2": [5, 6, 7, 8, 9], "group_1": [1, 1, 1, 1, 2], "group_2": [None, 1, 2, 1, None], "group_3": [None, None, None, 1, None], } ) # 1. 提取每行的有效层级路径:将非NaN的group值组成元组 group_columns = [col for col in df.columns if col.startswith("group_")] df["hierarchy_path"] = df[group_columns].apply( lambda row: tuple(v for v in row if pd.notna(v)), axis=1 ) # 2. 创建路径与节点的映射,每个节点包含数据字段和空children列表 node_map = {} for _, row in df.iterrows(): node = { "var1": row["var1"], "var2": row["var2"], "children": [] } node_map[row["hierarchy_path"]] = node # 3. 将子节点挂载到对应的父节点下 for path in node_map: if len(path) > 1: # 父路径为当前路径去掉最后一个层级 parent_path = path[:-1] node_map[parent_path]["children"].append(node_map[path]) # 4. 收集所有根节点(路径长度为1的节点) result = [node for path, node in node_map.items() if len(path) == 1] # 输出结果 print(result)
逻辑说明
- 构建层级路径:针对每行数据,提取所有非空的
group_*值,组成唯一标识层级位置的元组(如第4行的路径为(1,1,1),表示它属于group_1=1、group_2=1的子项)。 - 节点映射:为每个路径创建对应的节点字典,存储到映射表中,方便后续快速查找。
- 挂载子节点:遍历所有节点,若节点存在父层级,则将其添加到父节点的
children列表中。 - 收集根节点:所有路径长度为1的节点就是最顶层的根节点,将它们收集起来即为最终的嵌套数组。
内容的提问来源于stack exchange,提问作者g_t_m
相关产品推荐
相关产品推荐

