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

如何通过CSV两列字符串匹配构建Networkx分类支序图?

解决NetworkX分类支序图的节点连接问题

问题背景

我正在大学项目中使用NetworkX制作分类支序图,需要将分类名称(taxon_name)与其父级名称(parent_name)连接,从物种名向上关联至科名直至支序图根部。需要比对CSV文件中这两列的名称并生成节点间的边,但当前代码无法实现预期的列搜索匹配。

原尝试代码

import networkx as nx
import pandas as pd
import matplotlib.pyplot as plt


#df = pd.read_csv("E:/Escritorio/tp mat 3/pbdb_data.csv") #direccion labo
df = pd.read_csv("D:/unsam/mat 3/TP 1/pbdb_data.csv") #direccion pc
df = df.drop(["orig_no","taxon_no","record_type","flags","difference","accepted_no","parent_no","immpar_no","immpar_name","container_no","reference_no","is_extant"], axis=1)

print(df)

G = nx.Graph()
G.add_nodes_from(df["taxon_name"])

for i in df["parent_name"]:
    for j in df["taxon_name"]:
        if df[i] == df[j]:
            x =+ 1

print (x)
nx.draw_networkx(G)
plt.draw()

CSV数据示例

taxon_rank,taxon_name,accepted_rank,accepted_name,parent_name,n_occs
unranked clade,Dinosauria,unranked clade,Dinosauria,Dinosauriformes,1952
unranked clade,Megalosauridae,unranked clade,Megalosauridae,Dinosauria,2
unranked clade,Ornithischia,unranked clade,Ornithischia,Dinosauria,236
unranked clade,Genasauria,unranked clade,Genasauria,Ornithischia,208
unranked clade,Cerapoda,unranked clade,Cerapoda,Genasauria,173

原代码问题分析

  • 嵌套循环遍历取值的方式效率极低,且df[i]用法错误:i是parent_name的具体分类名称,不是DataFrame的列名,会触发KeyError。
  • 仅做匹配计数,未实际创建节点间的连接边。
  • 无向图nx.Graph不适合体现层级分类的父子关系,有向图更贴合需求。
  • 未处理parent_name不在taxon_name中的根节点(如示例中的Dinosauriformes),会导致这类节点缺失。

修正后的代码

import networkx as nx
import pandas as pd
import matplotlib.pyplot as plt

# 读取并清理数据
df = pd.read_csv("D:/unsam/mat 3/TP 1/pbdb_data.csv")
drop_cols = ["orig_no","taxon_no","record_type","flags","difference","accepted_no","parent_no","immpar_no","immpar_name","container_no","reference_no","is_extant"]
df = df.drop(drop_cols, axis=1)

# 创建有向图,适合层级分类结构
G = nx.DiGraph()

# 添加所有节点:包含taxon_name和parent_name的所有值,避免根节点丢失
all_nodes = set(df["taxon_name"]) | set(df["parent_name"])
G.add_nodes_from(all_nodes)

# 遍历每行数据,添加父节点到子节点的边
for _, row in df.iterrows():
    G.add_edge(row["parent_name"], row["taxon_name"])

# 绘制支序图,使用层级布局更清晰
plt.figure(figsize=(12, 8))
# 使用graphviz的dot布局需提前安装Graphviz工具和pygraphviz库,若无则替换为nx.spring_layout
try:
    pos = nx.nx_agraph.graphviz_layout(G, prog="dot")
except ImportError:
    pos = nx.spring_layout(G, k=0.15)  # 备选布局

nx.draw_networkx(G, pos, with_labels=True, node_size=2000, font_size=10, arrows=True)
plt.title("分类支序图")
plt.axis("off")
plt.show()

代码说明

  • 改用nx.DiGraph有向图,清晰体现父级到子级的层级指向。
  • 合并两类名称作为节点集合,确保所有父节点(包括不在当前分类列表中的根节点)都被添加。
  • 通过iterrows()遍历行数据直接创建边,逻辑简洁高效。
  • 提供两种布局方案:优先使用Graphviz的dot布局生成标准层级图,若环境不支持则改用弹簧布局作为备选。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 22:25:59