如何在networkx中为边添加新属性?

38 投票
6 回答
41911 浏览
提问于 2025-05-01 00:58

我现在有:一个用networkx导入的图G,节点和边是通过gml文件加载的。

问题:如何给选定的边E添加一个新的属性。

我想做的:我想给图中的某条特定边E添加一个新的属性'类型'。注意:这个属性'类型'在边E上是不存在的。

我的代码是:

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

但是如果我打印出G的所有边,现在我有n+1条边;所有旧的边和一条新的边p= (id_source, id_target, {'type'= value})。而且,旧的边E(我想修改的那条)并没有新属性'类型'。

所以我的代码添加了一条新的边(这是我不想要的)。

我想更新旧的边,添加一个不存在的新属性。

暂无标签

6 个回答

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

这是来自提问者的解决方案:

感谢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)
1

下面Xin-Feng Li的回答是有效的,不过要注意,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']
3

我不太明白你为什么只想给一条边添加一个属性,其实你可以给所有的边添加一个属性,然后再把你想要的值给特定的那条边。

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

31

你可能在使用的是一个叫做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'})]

而对于多重图,则多了一个键的层级来跟踪并行的边,所以它的工作方式会有些不同。如果你没有明确设置一个键,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'})]

撰写回答