我有:在networkx中导入的图G,其节点和边由gml文件加载。
问题:如何向选定的边E添加新属性。
我想要做什么:我想为图表的特定边 E 添加一个新属性“类型”。注意:该边 E 不存在属性“type”。
我的代码是:
G.edge[id_source][id_target]['type']= value
但是如果我打印G的所有边,现在我有n+1条边; G 的所有旧边和新边 p= (id_source, id_target, {'type'= value})。此外,旧边 E(我要修改的边)没有新属性“类型”。
所以我的代码添加了一个新的边缘(我不想要)。
我想更新旧属性,添加一个不存在的新属性。
您可能有一个networkx MultiGraph而不是图,在这种情况下,边的属性设置有点棘手。 (您可以通过加载节点之间具有多个边的图来获得多重图)。您可能会通过分配属性来破坏数据结构
G.edge[id_source][id_target]['type']= value
当你需要的时候
G.edge[id_source][id_target][key]['type']= value
。
以下示例说明了它对于图和多重图的工作方式有何不同。
对于图形案例属性的工作方式如下:
In [1]: import networkx as nx
In [2]: G = nx.Graph()
In [3]: G.add_edge(1,2,color='red')
In [4]: G.edges(data=True)
Out[4]: [(1, 2, {'color': 'red'})]
In [5]: G.add_edge(1,2,color='blue')
In [6]: G.edges(data=True)
Out[6]: [(1, 2, {'color': 'blue'})]
In [7]: G[1][2]
Out[7]: {'color': 'blue'}
In [8]: G[1][2]['color']='green'
In [9]: G.edges(data=True)
Out[9]: [(1, 2, {'color': 'green'})]
使用 MultiGraphs 时,有一个额外级别的键来跟踪平行边,因此它的工作方式略有不同。如果您没有显式设置键,MultiGraph.add_edge() 将使用内部选择的键(连续整数)添加一条新边。
In [1]: import networkx as nx
In [2]: G = nx.MultiGraph()
In [3]: G.add_edge(1,2,color='red')
In [4]: G.edges(data=True)
Out[4]: [(1, 2, {'color': 'red'})]
In [5]: G.add_edge(1,2,color='blue')
In [6]: G.edges(data=True)
Out[6]: [(1, 2, {'color': 'red'}), (1, 2, {'color': 'blue'})]
In [7]: G.edges(data=True,keys=True)
Out[7]: [(1, 2, 0, {'color': 'red'}), (1, 2, 1, {'color': 'blue'})]
In [8]: G.add_edge(1,2,key=0,color='blue')
In [9]: G.edges(data=True,keys=True)
Out[9]: [(1, 2, 0, {'color': 'blue'}), (1, 2, 1, {'color': 'blue'})]
In [10]: G[1][2]
Out[10]: {0: {'color': 'blue'}, 1: {'color': 'blue'}}
In [11]: G[1][2][0]['color']='green'
In [12]: G.edges(data=True,keys=True)
Out[12]: [(1, 2, 0, {'color': 'green'}), (1, 2, 1, {'color': 'blue'})]
我不太明白为什么你只想向一条边添加属性,相反,你可以向所有边添加属性,然后将
the wanted value
赋予特定的边。
Networkx 有一个名为
set_edge_attributes
的方法可以为所有边添加边属性,例如
G = nx.path_graph(3)
bb = nx.edge_betweenness_centrality(G, normalized=False)
nx.set_edge_attributes(G, 'betweenness', bb)
G[1][2]['betweenness']
输出:2.0
李新峰的以下答案有效,只需注意
values
和 name
的参数在 Networkx v1.x(最初编写答案时)和 Networkx v2.x 之间切换。对于 v2.x,代码是:
G = nx.path_graph(3)
bb = nx.edge_betweenness_centrality(G, normalized=False)
nx.set_edge_attributes(G, bb, 'betweenness')
G[1][2]['betweenness']
从OP的问题中添加的解决方案:
感谢 Aric 和一些技巧,我解决了我的问题:
def add_attribute_to_edge(H,id_node_source,id_node_target,new_attr,value_attr): keydict =H[id_node_source][id_node_target] key=len(keydict) for k in keydict: if 'type' not in H.edge[id_source][id_target][k]: H.add_edge(id_node_source,id_node_target,key=k, new_attr= value_attr)
实际上,有一种更好、更短的方法可以向图中的现有边添加新属性:
>>> for itr in G.edges_iter(None, True, True):
itr
(0, 1, {})
(0, 2, {'edge': (0, 2)})
(0, 3, {})
(0, 4, {})
(1, 2, {})
(1, 3, {})
(2, 3, {})
(2, 4, {})
(3, 4, {})
>>> G[0][1].update(edge=(0,1)) #This will add 'edge'=(0,1) dict item to edge(0,1)
>>> for itr in G.edges_iter(None, True, True):
itr
(0, 1, {'edge': (0, 1)})
(0, 2, {'edge': (0, 2)})
(0, 3, {})
(0, 4, {})
(1, 2, {})
(1, 3, {})
(2, 3, {})
(2, 4, {})
(3, 4, {})
nx.set_edge_attributes( G, { (id_源,id_目标):{ '类型1':值1, '类型2':值2, '类型3':值3, } }, )