2014-11-01 7 views
11

was ich habe: ein Graph G importiert in NetworkX Whit Knoten und egdes von GML-Datei geladen.
Problem: i für eine bestimmte Kante E meiner Graph ein neues Attribut ‚Typ‘ hinzufügen möchten: Wie ein neues Attribut zu einer ausgewählten Kante E.
Was ich tun möchte hinzufügen. Achtung: Das Attribut ‚Typ‘ existiert nicht für diese Kante E.hinzufügen neues Attribut zu einer Kante in NetworkX

Ich las viel von Lösungen im Internet vorgeschlagen und hier, aber keiner dieser Lösungen löst mein Problem. In der Tat ist mein Code:

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

Aber wenn ich alle Kanten von G drucken, jetzt habe ich n + 1 Kanten, alle alten Kanten von G, und eine neue Kante p = (id_source, id_target, {'Typ' = Wert}). Außerdem hat die alte Kante E (die eine, die ich modifizieren möchte) nicht das neue Attribut 'type'.

So habe meinen Code eine neue Kante hinzugefügt (das ich will nicht).
Ich mag die alten ein neues Attribut aktualisieren, hinzufügen, die nicht existiert.

Vielen Dank für Ihre Hilfe!

EDIT: GELÖST Dank Aric und ein paar Tricks, die ich mein Problem gelöst:

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) 

Antwort

7

Sie einen NetworkX Multigraphen statt eines Graphen in diesem Fall kann und das Attribut für Kanten Einstellung ist ein kleiner Trick. (Sie können einen Multigraph erhalten, indem Sie einen Graphen mit mehr als einer Kante zwischen Knoten laden). Sie können die Datenstruktur werden korrumpiert durch die Zuordnung des Attributs G.edge[id_source][id_target]['type']= value wenn Sie G.edge[id_source][id_target][key]['type']= value benötigen.

Hier sind Beispiele dafür, wie es funktioniert anders für Graphen und Multigraphen.

Für den Graph Fall Attribute wie diese Arbeit:

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

Mit Multigraphen eine zusätzliche Ebene des Schlüssels, den Überblick über die parallelen Kanten zu halten, damit es ein wenig anders funktioniert. Wenn Sie keinen Schlüssel explizit festlegen, fügt MultiGraph.add_edge() eine neue Kante mit einem intern ausgewählten Schlüssel hinzu (sequenzielle Ganzzahlen).

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

Danke für Antwort. Aber in Multigraph-Beispiel, wenn Sie die Kante hinzufügen, fügen Sie auch die Attributfarbe hinzu. Ich muss ein neues Attribut hinzufügen, das nicht existiert, wenn ich die Kante erstellt habe. Zum Beispiel nach Zeile 3, wie kann ich der Kante 1-2 ein zweites Attribut hinzufügen? –

+0

Sicher schreiben Sie einfach G.add_edge (1,2, andere = 'foo'). Sie möchten vielleicht nicht 'type' verwenden, da es in Python ein reserviertes Wort ist (obwohl es wahrscheinlich OK ist, so zu verwenden). – Aric

+0

Aber ich versuchte G.add_edge (1,2, andere = 'foo'). Aber es fügt eine neue Kante um die erste Kante 1,2, Farbe: rot). Ich will das: (1,2, Farbe: rot, andere: foo). Wie kann ich dieses Ergebnis erhalten? –

1

Ich verstehe nicht ganz, warum Sie nur eine Kante ein Attribut hinzufügen möchten, stattdessen können Sie ein Attribut für alle Kanten hinzufügen, können Sie dann die the wanted value Ihren spezifischen Vorteil.

NetworkX hat eine Methode genannt set_edge_attributes kann eine Kante zu allen Kanten hinzuzufügen Attribute, zum Beispiel

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

Output: 2.0

0

Eigentlich gibt es einen besseren und kurzen Weg, um neue Attribute zu einer bestehenden Kante in einem Diagramm hinzuzufügen:

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