2014-11-01 44 views
11

Co mam: graf G importowany w networkx whit węzły i egdes załadowany przez plik gml.
Problem: Jak dodać nowy atrybut do wybranej krawędzi E.
Co chcę zrobić: Chcę dodać nowy atrybut „typ” dla danej krawędzi E mojego wykresu. Uwaga: atrybut "typ" nie istnieje dla tej krawędzi E.Dodaj nowy atrybut do krawędzi w siecix

Przeczytałem wiele rozwiązań proponowanych w Internecie i tutaj, ale żadne z tych rozwiązań nie rozwiązuje mojego problemu. W rzeczywistości mój kod to:

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

ale jeśli wydrukować wszystkie krawędzie G, teraz mam n + 1 krawędzie, wszystkie stare krawędzie g, a nowa krawędź p = (id_source, id_target, {'typ' = wartość}). Ponadto stara krawędź E (ta, którą chcę zmodyfikować) nie ma nowego atrybutu "typ".

Więc mój kod dodał nową krawędź (której nie chcę).
Chcę aktualizować starego, dodając nowy atrybut, który nie istnieje.

Dziękuję za pomoc!

EDIT: SOLVED Dzięki Arie i kilka sztuczek i rozwiązać mój problem:

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) 

Odpowiedz

7

Możesz mieć NetworkX multigraf zamiast wykresu iw tym wypadku atrybut ustawienie krawędzi jest trochę tricker. (Możesz uzyskać multigraph, ładując wykres z więcej niż jedną krawędzią między węzłami). Być może uszkodzisz strukturę danych, przypisując atrybut G.edge[id_source][id_target]['type']= value, gdy potrzebujesz G.edge[id_source][id_target][key]['type']= value.

Oto przykłady tego, jak działa inaczej w przypadku wykresów i wykresów MultiGraph.

Dla przypadku Graph atrybuty pracę tak:

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

Z MultiGraphs istnieje dodatkowy poziom klawiszy śledzić równoległych krawędziach tak to działa trochę inaczej. Jeśli nie ustawisz jawnie klucza, MultiGraph.add_edge() doda nową krawędź z wewnętrznie wybranym kluczem (sekwencyjne liczby całkowite).

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

Dzięki za odpowiedź. Ale w przypadku multigraph, kiedy dodajesz krawędź, dodajesz także kolor atrybutu. Potrzebuję dodać nowy atrybut, który nie istnieje, gdy utworzyłem krawędź. Na przykład po linii 3, w jaki sposób mogę dodać drugi atrybut do krawędzi 1-2 ???? –

+0

Oczywiście po prostu napisz G.add_edge (1,2, inny = 'foo'). Możesz nie chcieć używać 'type', ponieważ jest to słowo zarezerwowane w Pythonie (chociaż prawdopodobnie będzie w porządku, aby użyć tego w ten sposób). – Aric

+0

Ale próbowałem G.add_edge (1,2, inne = "foo"). Dodaje jednak nową krawędź inną przez pierwszą krawędź 1,2, kolor: czerwony). Chcę to: (1,2, kolor: czerwony, inny: foo). Jak mogę uzyskać ten wynik? –

1

ja nie bardzo rozumiem, dlaczego chcesz dodać atrybut tylko do jednej krawędzi, zamiast tego można dodać atrybut do wszystkich krawędzi, a następnie podać the wanted value do konkretnego krawędzi.

NetworkX ma metodę zwaną set_edge_attributes można dodać atrybutów krawędź na wszystkich krawędziach, na przykład

G = nx.path_graph(3) 
    bb = nx.edge_betweenness_centrality(G, normalized=False) 
    nx.set_edge_attributes(G, 'betweenness', bb) 
    G[1][2]['betweenness'] 

wyjściowe: 2.0

0

Faktycznie, istnieje lepszy i krótki sposób dodać nowe atrybuty do istniejącej krawędzi na wykresie:

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