2014-11-01 4 views
11

У меня есть: граф G, импортированный в узлах networkx whit и egdes, загружаемых gml-файлом.
Проблемы: Как добавить новый атрибут к выбранному краю E.
Что я хочу сделать: я хочу, чтобы добавить новый атрибут «типа» для конкретного ребра Е моего графика. Внимание: для этого ребра не существует атрибута 'type'.Добавить новый атрибут к краю в сетиx

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

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

Но если я напечатать все ребра G, теперь у меня есть п + 1 ребер, все старые ребра G, и новый фронт р = (id_source, id_target, {'type' = значение}). Кроме того, старый край E (тот, который я хочу изменить) не имеет нового атрибута «type».

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

Благодарим за помощь!

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

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) 

ответ

7

Вы можете иметь NetworkX мультиграф вместо графа и в этом случае установка для ребер атрибута немного обманом. (Вы можете получить мультиграфию, загрузив граф с несколькими границами между узлами). Вы можете повредить структуру данных, назначив атрибут G.edge[id_source][id_target]['type']= value, если вам нужно G.edge[id_source][id_target][key]['type']= value.

Вот примеры того, как это работает по-разному для графиков и мультиграфов.

Для случая 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'})] 

С мультиграфами есть дополнительный уровень ключей, чтобы следить за параллельные края, так что работает немного по-другому. Если вы не указали явным образом ключ 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'})] 
+0

Спасибо за ответ. Но в мультиграфическом примере, когда вы добавляете кромку, вы добавляете также цвет атрибута. Мне нужно добавить новый атрибут, который не существует, когда я создал ребро. Например, после строки 3, как я могу добавить второй атрибут к краю 1-2 ???? –

+0

Конечно, просто напишите G.add_edge (1,2, other = 'foo'). Возможно, вы не захотите использовать 'type', так как это зарезервированное слово в Python (хотя, вероятно, будет полезно использовать это как). – Aric

+0

Но я попробовал G.add_edge (1,2, other = 'foo'). Но он добавляет новый один край, отличный от первого края 1,2, цвет: красный). Я хочу Это: (1,2, цвет: красный, другое: foo). Как я могу получить этот результат? –

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

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, {}) 
Смежные вопросы