Добавить новый атрибут к краю в 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, {})