我已经提取了一些我曾经在网络x的1.6.1中使用过的代码。在1.8.1上,当写入gml
或graphml
时,它不起作用。
问题归结为无法在数据字典中写入边缘属性,如下所示:
BasicGraph = nx.read_graphml("KeggCompleteEng.graphml")
for e,v in BasicGraph.edges_iter():
BasicGraph[e][v]['test'] = 'test'
nx.write_graphml(BasicGraph, "edgeTester.graphml")
导致错误:
AttributeError: 'str' object has no attribute 'items'
当我使用:for e,v,data in BasicGraph.edges_iter(data=True):
时,数据打印出来如下:
{'root_index': -3233, 'label': u'unspecified'}
test
AKA新属性在字典之外。
文档说我应该能够像上面那样做。但是,我想我犯了一个愚蠢的错误,并希望被放回正确的道路上!
编辑:
所以我用程序中生成的图形运行程序:BasicGraph = nx.complete_graph(100)
它运行正常。
然后我使用引物中的示例graphml文件运行它:BasicGraph = nx.read_graphml("graphmltest.graphml")
并且它也有效。 (我甚至导入和导出Cytoscape以检查这不是问题)
很明显,这是我正在使用的文件。 Here's指向它的链接,任何人都可以看到它有什么问题吗?
答案 0 :(得分:3)
问题是您的图形具有平行边缘,因此NetworkX将其作为MultiGraph对象加载:
In [1]: import networkx as nx
In [2]: G = nx.read_graphml('KeggCompleteEng.graphml')
In [3]: type(G)
Out[3]: networkx.classes.multigraph.MultiGraph
In [4]: G.number_of_edges()
Out[4]: 7123
In [5]: H = nx.Graph(G) # convert to graph, remove parallel edges
In [6]: H.number_of_edges()
Out[6]: 6160
因为边缘的图形对象存储的内部结构是G [node] [node] [key] [attribute] = value(注意多图的额外关键字典级别)。
您正在通过
明确修改结构for e,v in BasicGraph.edges_iter():
BasicGraph[e][v]['test'] = 'test'
打破了它。
允许以这种方式修改数据结构,但使用NetworkX API更安全
In [7]: G = nx.MultiGraph()
In [8]: G.add_edge(1,2,key='one')
In [9]: G.add_edge(1,2,key='two')
In [10]: G.edges(keys=True)
Out[10]: [(1, 2, 'two'), (1, 2, 'one')]
In [11]: G.add_edge(1,2,key='one',color='red')
In [12]: G.add_edge(1,2,key='two',color='blue')
In [13]: G.edges(keys=True,data=True)
Out[13]: [(1, 2, 'two', {'color': 'blue'}), (1, 2, 'one', {'color': 'red'})]