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

如何使用Pandas将列状层级结构转换为父子列表?

用Pandas将固定列层级数据转换为邻接表的问题

示例层级

Books
                     /     |     \
             Science     (null)      (null)
               /           |           \
      Astronomy          (null)          Pictures       
         /  \              |                      \
Astrophysics Cosmology   (null)                    Astronomy
      /         \          |                       /    |    \
  (null)        (null)   Amateurs_Astronomy   Galaxies Stars Astronauts

原始数据(data.csv)

id,level_1,level_2,level_3,level_4,level_5
1,Books,Science,Astronomy,Astrophysics,
2,Books,Science,Astronomy,Cosmology,
3,Books,,,,Amateurs_Astronomy
4,Books,,Pictures,Astronomy,Galaxies
5,Books,,Pictures,Astronomy,Stars
6,Books,,Pictures,Astronomy,Astronauts

当前问题

已尝试为节点添加UUID列,但存在两个核心问题:

  • 相同节点会生成不同UUID(比如第1、2行的level_3节点Astronomy应共用同一个UUID)
  • 不知道如何跳过空值,准确找到每个节点的父节点

期望生成如下格式的邻接表:

this_node,parent_node,this_node_uuid,parent_node_uuid
Science,Books,books/science-node-uuid,books-node-uuid
Astronomy,Science,books/science/astronomy-node-uuid,books/science/astronomy-node-uuid
Astrophysics,Astronomy,books/science/astronomy/astrophysics-node-uuid,books/science/astronomy-node-uuid
Amateurs_Astronomy,Books,books/amateurs_astronomy-node-uuid,books-node-uuid

解决方案

核心思路

  1. 统一节点UUID:用字典存储所有唯一节点,每个节点只生成一次UUID
  2. 追踪父节点:遍历每行数据时,跳过空值,动态更新当前节点的父节点
  3. 生成邻接表:从节点字典中提取父子关系,格式化输出

代码实现

import pandas as pd
import uuid

# 读取数据
df = pd.read_csv('data.csv')

# 初始化节点映射字典,存储每个节点的UUID、路径、父节点
node_map = {}
root_col = 'level_1'

# 处理根节点(level_1)
for root_node in df[root_col].dropna().unique():
    node_map[root_node] = {
        'uuid': str(uuid.uuid4()),
        'path': root_node.lower(),
        'parent': None
    }

# 遍历每行数据,构建节点映射
for _, row in df.iterrows():
    current_parent = row[root_col]
    # 从level_2到level_5依次处理
    for level_num in range(2, 6):
        col_name = f'level_{level_num}'
        current_node = row[col_name]
        
        # 跳过空值节点
        if pd.isna(current_node):
            continue
        
        # 节点未记录时,生成UUID并关联父节点
        if current_node not in node_map:
            parent_info = node_map[current_parent]
            node_uuid = str(uuid.uuid4())
            node_path = f"{parent_info['path']}/{current_node.lower()}"
            
            node_map[current_node] = {
                'uuid': node_uuid,
                'path': node_path,
                'parent': current_parent
            }
        
        # 更新当前父节点为当前节点,用于下一层级的子节点
        current_parent = current_node

# 生成邻接表
adjacency_records = []
for node, info in node_map.items():
    parent_node = info['parent']
    if parent_node is not None:
        parent_info = node_map[parent_node]
        adjacency_records.append({
            'this_node': node,
            'parent_node': parent_node,
            'this_node_uuid': f"{info['path']}-{info['uuid'][:8]}",  # 取UUID前8位简化格式
            'parent_node_uuid': f"{parent_info['path']}-{parent_info['uuid'][:8]}"
        })

# 转换为DataFrame并去重
adjacency_df = pd.DataFrame(adjacency_records).drop_duplicates()
print(adjacency_df)

代码说明

  • 节点映射字典:确保每个节点只生成一次UUID,避免重复
  • 行遍历逻辑:逐行处理时,动态跟踪当前父节点,遇到空值直接跳过,保证父节点定位准确
  • UUID格式:采用路径-短UUID的格式,和示例格式一致,同时保证唯一性
  • 去重处理:避免多行数据中重复的父子关系被多次记录

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 15:50:26