我运行这个程序:
import networkx as nx
from pylab import *
g=nx.Graph()
g.add_edge('a','b', weight=3)
g.add_edge('a','c', weight=2)
g.add_edge('b','c', weight=7)
w=nx.get_edge_attributes(g, 'weight')
w[('b','a')]=3
w[('c','a')]=2
w[('c','b')]=7
我不明白为什么w
dict只包含5个而不是6个项目:
{('b', 'a'): 3, ('c', 'a'): 2, ('a', 'b'): 3, ('c', 'b'): 7, ('a', 'c'): 2}
('b','c')
条目已消失......
我在这里做错了什么?
答案 0 :(得分:2)
您的图表不是定向的。这是问题的根本原因。
运行代码的第一部分时:
import networkx as nx
from pylab import *
g=nx.Graph()
g.add_edge('a','b', weight=3)
g.add_edge('a','c', weight=2)
g.add_edge('b','c', weight=7)
w=nx.get_edge_attributes(g, 'weight')
将w
放入dict中,每个dict的键都是其中一个边。但是边缘内的节点顺序并不重要。所以,让我们看一下w
:
w
> {('a', 'b'): 3, ('a', 'c'): 2, ('c', 'b'): 7}
注意---您为('b', 'c')
定义了边缘权重。但是在w
中,它与密钥('c','b')
一起存储。
所以稍后,当你定义w[('c','b')]
时,你会覆盖它。其他边缘没有发生这种情况,因为随机偶然发生的网络碰巧按照你预期的顺序返回它们。
我认为您正在尝试定义w
,以便无论您检查的边缘顺序如何,您的权重都相同。
最好使用内置的networkx命令来获取权重而不要使用w
:
g.get_edge_data('a','b')['weight']
但是,如果你真的想要w
,那么一种方法是循环使用w
的键作为
for edge in w:
w[([edge[1],edge[0])] = w[edge]
或者您可以定义一个函数
def f(edge,w):
if edge in w:
return w[edge]
else:
return w[(edge[1],edge[0])
对正在发生的事情进行更多解释:
你不能假设networkx会以与给定它们相同的顺序返回无向图的边缘。它是一个无向图,所以任何假定边缘隐含方向的东西都会遇到麻烦。
基本上这是因为networkx将节点存储在字典结构中。因此,您不能假设它以任何顺序返回节点。因此,特别是在networkx寻找其边缘的情况下,它以某种顺序通过节点。在这种情况下,它会在到达'c'
之前到达'b'
。所以它首先获得了c
的优势。当它到达b
时,它知道它已经有了这个边缘,所以它就会把它留下来。
答案 1 :(得分:1)
我发现了(经过一些尝试并查看了get_edge_attribute的代码)。在此方法本身中,边缘在此处被检索:
if G.is_multigraph():
edges = G.edges(keys=True, data=True)
else:
edges = G.edges(data=True)
return dict( (x[:-1], x[-1][name]) for x in edges if name in x[-1] )
在您的情况下,图表不是多图。所以它根据G.edges()返回的列表构建字典。所以我用以下代码做了一点测试:
g.add_edge('a','b', weight=3)
print "edges after adding 'ab': " + str(g.edges(data=True))
g.add_edge('a','c', weight=2)
print "edges after adding 'ac': " + str(g.edges(data=True))
g.add_edge('b','c', weight=7)
print "edges after adding 'bc': " + str(g.edges(data=True))
输出:
edges after adding 'ab': [('a', 'b', {'weight': 3})]
edges after adding 'ac': [('a', 'c', {'weight': 2}), ('a', 'b', {'weight': 3})]
edges after adding 'bc': [('a', 'c', {'weight': 2}), ('a', 'b', {'weight': 3}), ('c', 'b', {'weight': 7})]
查看输出中的最后一行:我们添加了边缘' bc'不是' cb',但在边缘列表中,没有'''边缘,而不是有一个' cb'边缘。这就是为什么你没有看到边缘' bc'因为它不存在。
我不知道确切的原因,为什么会这样做。