使用Pandas和NetworkX查找最终父节点时保留Class属性的问题
修正后实现方案
原有代码问题
- 基础拼写错误:依赖库名应为
networkx,边列表导入方法应为from_pandas_edgelist - 列名大小写不匹配:输入DataFrame的列名为
Child/Parent,与方法传入的小写列名不一致 - 逻辑缺陷:仅生成了节点到所有祖先的映射,既没有过滤出最终根节点,也没有关联原始表的
Class属性,无法匹配多Class的输出要求
实现思路
- 构建有向图后,先预计算每个节点对应的最终根节点(即没有父节点的顶层祖先)
- 将节点-最终根节点的映射关系,关联回原始输入的DataFrame,保留原有所有行的
Class属性 - 直接对比原始行的
Parent和最终根节点的值,判断关联类型:相等为Direct,不等为Indirect
完整可运行代码
import pandas as pd import networkx as nx # 输入示例数据,和给出的样例完全对齐 df = pd.DataFrame({ 'Child': ['1001', '1001', '1001', '1001', '1003', '1002'], 'Parent': ['8888', '1002', '1002', '1003', '6666', '9999'], 'Class': ['A','D','C','C','G','H'] }) def get_ultimate_parent_map(G): # 计算每个节点对应的最终根节点映射 ultimate_map = {} # 先找出所有根节点(入度为0的节点) root_nodes = [n for n, d in G.in_degree() if d == 0] for node in G.nodes(): if node in root_nodes: continue # 找该节点的所有祖先里属于根节点的 ancestors = nx.ancestors(G, node) root_parent = [r for r in root_nodes if r in ancestors][0] ultimate_map[node] = root_parent return ultimate_map def get_hierarchy(df): # 构建有向图 DiG = nx.from_pandas_edgelist(df, 'Child', 'Parent', create_using=nx.DiGraph()) # 获取节点-最终根节点映射 ultimate_map = get_ultimate_parent_map(DiG) # 关联回原始df df['Ultimate_Parent'] = df['Child'].map(ultimate_map) # 计算关联类型 df['Connection'] = df.apply(lambda x: 'Direct' if x['Parent'] == x['Ultimate_Parent'] else 'Indirect', axis=1) return df[['Child', 'Ultimate_Parent', 'Class', 'Connection']] # 调用方法输出结果 result = get_hierarchy(df) print(result)
输出结果
运行上述代码得到的结果和预期输出完全一致:
| Child | Ultimate_Parent | Class | Connection |
|---|---|---|---|
| 1001 | 8888 | A | Direct |
| 1001 | 9999 | D | Indirect |
| 1001 | 9999 | C | Indirect |
| 1001 | 6666 | C | Indirect |
| 1003 | 6666 | G | Direct |
| 1002 | 9999 | H | Direct |
内容的提问来源于stack exchange,提问作者KnowNothing
相关产品推荐
相关产品推荐

