使用NetworkX查找多父节点及M:N关系表关联的技术问题
NetworkX实现M:N关联表的图结构转换需求
没问题!NetworkX完全能搞定你这个需求,咱们可以通过识别M:N节点、遍历其出边,再重构图结构的方式,实现把P2通过MN12关联到P1的目标。
实现步骤拆解
- 首先定位目标M:N节点(这里是标记为红色的
MN12) - 获取该节点的所有出边,找到它连接的目标节点集合(P1、P2)
- 移除原M:N节点及其所有关联边
- 保留其中一个目标节点(比如P1)的原有连接,为其他节点创建带关联标识的新节点(比如
P2(using MN12)) - 把新节点连接到保留的目标节点上,并设置对应的节点属性
完整实现代码
from pathlib import Path import subprocess import networkx as nx def write_svg(g, name): temp = "temp.dot" suffix = "jpg" nx.nx_agraph.write_dot(g, temp) pa_img = Path(f"{name}.{suffix}") li_cmd = f"/opt/local/bin/dot {temp} -T {suffix} -o {pa_img}".split() subprocess.check_output(li_cmd) # 初始化原始图 G = nx.DiGraph() G.add_edge("C1", "P1") G.add_edge("C2", "P1") G.add_edge("C21", "C2") G.add_edge("MN12", "P1") G.add_edge("MN12", "P2") G.add_nodes_from([ ("MN12", {"color" : "red"}) ]) # 开始处理M:N节点 # 1. 定位M:N节点(这里通过颜色属性识别,也可以用命名规则) mn_node = next(node for node, attrs in G.nodes(data=True) if attrs.get("color") == "red") # 2. 获取该节点的所有出边目标 target_nodes = [target for _, target in G.out_edges(mn_node)] # 3. 移除原M:N节点及其边 G.remove_node(mn_node) # 4. 重构关联:以第一个目标节点为核心,将其他节点转为带标识的新节点并关联 if len(target_nodes) >= 2: core_node = target_nodes[0] # 这里选P1作为核心 for node in target_nodes[1:]: new_node_name = f"{node}(using {mn_node})" G.add_edge(new_node_name, core_node) G.add_nodes_from([(new_node_name, {"color": "green"})]) # 生成可视化图 write_svg(G, "transformed_graph")
关键代码说明
- 用
G.out_edges(mn_node)可以轻松获取该节点的所有出边目标,这正是你需要确认的MN12指向P1和P2的关联关系 - 通过
next(...)遍历节点属性找到红色的M:N节点,如果你有多个M:N节点,可以改成循环处理 - 移除原节点用
G.remove_node(),它会自动删除该节点的所有关联边,不用单独处理边的删除
这样处理后,你就能得到想要的图结构:P2(using MN12)直接连接到P1,同时保留了原有其他节点的关联。
内容的提问来源于stack exchange,提问作者JL Peyret
相关产品推荐
相关产品推荐

