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

将带边属性的有向图转为无向图时,如何保留所有边及属性?

有向多重图转无向图时保留所有边属性的问题

我尝试将带边属性的有向网络图转换为无向图并保留所有边属性,但转换后丢失了weight为3的边。以下是复现代码:

import networkx as nx
g = nx.MultiDiGraph()

g.add_edge(1, 2, weight= 3)
g.add_edge(1, 2, weight= 4)
g.add_edge(2, 1, weight= 5)
g.add_edge(1, 3, weight= 2)
g.add_edge(2, 3, weight= 1)

# 添加节点属性
g.nodes[1]["property"] = "A"
g.nodes[2]["property"] = "B"
g.nodes[3]["property"] = "C"

print(g.edges(data=True))
print(g.nodes(data=True))
print("_____________________________________________"*2)

h = g.copy().to_undirected(reciprocal=False)
print(h.edges(data=True))
print(h.nodes(data=True))

输出结果显示weight为3的边丢失,且部分边的weight被合并:

[(1, 2, {'weight': 3}), (1, 2, {'weight': 4}), (1, 3, {'weight': 2}), (2, 1, {'weight': 5}), (2, 3, {'weight': 1})]
[(1, {'property': 'A'}), (2, {'property': 'B'}), (3, {'property': 'C'})]
__________________________________________________________________________________________
[(1, 2, {'weight': 9}), (1, 3, {'weight': 2}), (2, 3, {'weight': 1})]
[(1, {'property': 'A'}), (2, {'property': 'B'}), (3, {'property': 'C'})]

我需要保留所有三条边,得到如下结果:

[(1, 2, {'weight': 3}), (1, 2, {'weight': 4}), (1, 2, {'weight': 5}), (1, 3, {'weight': 2}), (2, 3, {'weight': 1})]

这不是NetworkX的bug,是默认行为导致的

to_undirected()方法默认会合并同对节点间的边,对于数值型属性(比如weight),默认的聚合逻辑是求和。当设置reciprocal=False时,它会把所有方向的边转为无向边,但合并逻辑会将(1,2)、(2,1)的边合并,导致属性被聚合,部分边的原始属性丢失。

解决方案:手动遍历添加所有边

要保留所有边及其原始属性,需要创建一个无向多重图(MultiGraph),然后手动遍历原有的有向图的所有边,逐个添加到新图中。这样可以避免默认的合并逻辑,完整保留每条边的属性。

修改后的代码如下:

import networkx as nx

g = nx.MultiDiGraph()

g.add_edge(1, 2, weight=3)
g.add_edge(1, 2, weight=4)
g.add_edge(2, 1, weight=5)
g.add_edge(1, 3, weight=2)
g.add_edge(2, 3, weight=1)

# 添加节点属性
g.nodes[1]["property"] = "A"
g.nodes[2]["property"] = "B"
g.nodes[3]["property"] = "C"

# 创建空的无向多重图
h = nx.MultiGraph()
# 复制所有节点及其属性
h.add_nodes_from(g.nodes(data=True))
# 遍历原有的每条边,添加到无向图中
for u, v, attrs in g.edges(data=True):
    h.add_edge(u, v, **attrs)

# 输出结果
print(h.edges(data=True))
print(h.nodes(data=True))

运行后会得到预期的输出:

[(1, 2, {'weight': 3}), (1, 2, {'weight': 4}), (1, 2, {'weight': 5}), (1, 3, {'weight': 2}), (2, 3, {'weight': 1})]
[(1, {'property': 'A'}), (2, {'property': 'B'}), (3, {'property': 'C'})]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 06:35:12