Добавить новый атрибут к краю в networkx

что у меня есть: граф G, импортированный в networkx whit nodes и egdes, загруженный файлом gml.
: как добавить новый атрибут к выбранному краю E.
что я хочу сделать: Я хочу добавить новый атрибут "type" для определенного ребра E моего графика. Внимание: атрибут "type"не существует для этого края E.

Я читал много решений, предложенных в интернете и здесь, но ни одно из этих решений не решает мою проблема. На самом деле мой код:

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

но если я напечатаю все ребра G, Теперь у меня есть N+1 ребер, все старые ребра G и новое ребро p= (id_source, id_target, {'type'= value}). Кроме того, старый edge E (тот, который я хочу изменить) не имеет нового атрибута "type".

поэтому мой код добавил новое ребро (которое я не хочу).
Я хочу, чтобы обновить старый добавляет новый атрибут, который не существует.

Спасибо за вашу помощь !

редактировать: решить Благодаря Арику и некоторым трюкам я решил свою проблему:

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)

3 ответов


у вас может быть Мультиграф networkx вместо графика, и в этом случае настройка атрибута для ребер немного сложнее. (Вы можете получить мультиграф, загрузив график с более чем одним ребром между узлами). Вы можете повредить структуру данных, назначив атрибут 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'})]

С Мультиграфами существует дополнительный уровень ключей для отслеживания параллельных ребер, поэтому он работает немного по-другому. Если вы явно не задали ключевой Мультиграф.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


на самом деле, есть лучший и короткий способ добавить новые атрибуты к существующему краю в графике:

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