将新属性添加到networkx中的边缘

时间:2014-11-01 18:10:54

标签: python graph attributes networkx edge

我有什么:在gx文件加载的networkx whit节点和egdes中导入的图表G.
问题:如何将新属性添加到选定边缘。
我想做什么:我想为图表的特定边E添加新属性'type'。注意:此边E不存在属性“type”。

我在互联网和这里阅读了很多解决方案,但这些解决方案中没有一个解决了我的问题。 实际上我的代码是:

  G.edge[id_source][id_target]['type']= value

但是如果我打印G的所有边缘,现在我有n + 1条边,G的所有旧边和新边p =(id_source,id_target,{'type'= value})。此外,旧边E(我想要修改的边)没有新属性'type'。

所以我的代码添加了一个新的边缘(我不想要) 我想要更新旧版本添加不存在的新属性。

感谢您的帮助!

编辑已解决 感谢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)

5 个答案:

答案 0 :(得分:10)

你可能有一个networkx MultiGraph而不是图形,在这种情况下,边缘的属性设置有点小问题。 (您可以通过加载节点之间具有多个边缘的图形来获取多图形)。您可能通过分配属性来破坏数据结构  您需要时G.edge[id_source][id_target]['type']= value  G.edge[id_source][id_target][key]['type']= value

以下是Graphs和MultiGraphs的不同工作方式示例。

对于Graph案例属性,可以这样工作:

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'})]

答案 1 :(得分:1)

我不太清楚你为什么只想在一条边上添加一个属性,而是可以在所有边上添加一个属性,然后将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

答案 2 :(得分:0)

实际上,有一种更好的简短方法可以将新属性添加到图表中的现有边缘:

>>> 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, {})

答案 3 :(得分:0)

下面李新峰的答案起作用了,只是注意valuesname的参数在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']

答案 4 :(得分:0)

从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)