2014-11-01 16 views
11

Cosa ho: un grafico G importato in retex con nodi ed egdes caricati dal file gml.
Problema: Come aggiungere un nuovo attributo a un bordo selezionato E.
Quello che voglio fare: voglio aggiungere un nuovo attributo 'tipo' per un particolare bordo E del mio grafico. Attenzione: l'attributo 'tipo' non esiste per questo bordo E.Aggiungi un nuovo attributo a un bordo nella retex

Ho letto molte soluzioni proposte in Internet e qui, ma nessuna di queste soluzioni risolve il mio problema. In realtà il mio codice è:

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

Ma se stampo tutti gli archi di G, ora ho n + 1 bordi, tutti i vecchi archi di G, e un nuovo bordo p = (id_source, id_target, {'tipo' = valore}). Inoltre, il vecchio bordo E (quello che voglio modificare) non ha il nuovo attributo 'tipo'.

Quindi il mio codice ha aggiunto un nuovo bordo (che non voglio).
Desidero aggiornare quello vecchio aggiungendo un nuovo attributo che non esiste.

Grazie per il vostro aiuto!

EDIT: RISOLTO Grazie a Aric e alcuni trucchi ho risolto il mio problema:

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) 

risposta

7

Si può avere un multigrafo NetworkX invece di un grafico e in quel caso l'impostazione per i bordi attributo è un piccolo inganno. (È possibile ottenere una multigrafo caricando un grafico con più di un bordo tra i nodi). È possibile che si stia corrompendo la struttura dati assegnando l'attributo G.edge[id_source][id_target]['type']= value quando è necessario G.edge[id_source][id_target][key]['type']= value.

Ecco alcuni esempi di come funziona in modo diverso per Grafici e MultiGraph.

Per il caso Graph attributi lavoro simili:

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

Con multigrafi v'è un ulteriore livello di chiavi per tenere traccia dei bordi paralleli quindi funziona un po 'diverso. Se non si imposta esplicitamente una chiave, MultiGraph.add_edge() aggiungerà un nuovo spigolo con una chiave scelta internamente (interi sequenziali).

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

Grazie per risposta. Ma nell'esempio multigrafo quando aggiungi il bordo aggiungi anche il colore dell'attributo. Ho bisogno di aggiungere un nuovo attributo che non esiste quando ho creato il bordo. Ad esempio, dopo la riga 3, come posso aggiungere un secondo attributo al bordo 1-2 ???? –

+0

Certo, basta scrivere G.add_edge (1,2, other = 'foo'). Potresti non voler usare 'type' dato che è una parola riservata in Python (anche se probabilmente sarà OK da usare in questo modo). – Aric

+0

Ma ho provato G.add_edge (1,2, other = 'foo'). Ma aggiunge un nuovo bordo diverso dal primo bordo 1,2, colore: rosso). Voglio questo: (1,2, colore: rosso, altro: foo). Come posso ottenere questo risultato? –

1

io non capisco il motivo per cui si desidera aggiungere un attributo a un solo bordo, invece si può aggiungere un attributo a tutti i bordi, poi si dà il the wanted value a vostro vantaggio specifico.

NetworkX ha un metodo chiamato set_edge_attributes può aggiungere un bordo attribuisce a tutti i bordi, ad esempio

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

uscita: 2.0

0

realtà, c'è un modo migliore e breve per aggiungere nuovi attributi di uno spigolo esistente in un grafico:

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