web-dev-qa-db-fra.com

Ajouter un nouvel attribut à un Edge dans networkx

Ce que j'ai: un graphique G importé dans networkx avec des nœuds et des fichiers chargés par un fichier gml. 
Problème : Comment ajouter un nouvel attribut à un Edge E. sélectionné.
Ce que je veux faire: je veux ajouter un nouvel attribut 'type' pour un Edge E particulier de mon graphique. Attention: l'attribut 'type' n'existe pas pour cet Edge E.

J'ai lu beaucoup de solutions proposées sur Internet et ici, mais aucune de ces solutions ne résout mon problème. En fait, mon code est le suivant:

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

Mais si j’imprime tous les bords de G, j’ai maintenant n + 1 bords, tous les anciens bords de G et un nouveau bord p = (id_source, id_target, {'type' = valeur}). En outre, l'ancien Edge E (celui que je veux modifier) ​​ne possède pas le nouvel attribut 'type'.

Donc, mon code a ajouté un nouvel Edge (que je ne veux pas).
Je veux mettre à jour l’ancien en ajoutant un nouvel attribut qui n’existe pas.

Merci de votre aide !

EDIT:RÉSOLU Grâce à Aric et à quelques astuces, j'ai résolu mon problème:

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)
15
Stefano C.

Vous avez peut-être un graphe multi-réseau networkx au lieu d'un graphe et, dans ce cas, le paramètre d'attribut pour les contours est un peu plus compliqué. (Vous pouvez obtenir un multigraphe en chargeant un graphique avec plus d’un bord entre les nœuds). Vous pouvez endommager la structure de données en attribuant l'attribut G.Edge[id_source][id_target]['type']= value lorsque vous avez besoin de G.Edge[id_source][id_target][key]['type']= value.

Voici des exemples montrant comment cela fonctionne différemment pour les graphes et les multi-graphes. 

Pour les attributs de cas Graph, procédez comme suit:

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

Avec MultiGraphs, il existe un niveau supplémentaire de touches pour garder une trace des bords parallèles afin que cela fonctionne un peu différemment. Si vous ne définissez pas explicitement de clé, MultiGraph.add_Edge () ajoutera un nouvel Edge avec une clé choisie en interne (entiers séquentiels). 

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

Je ne comprends pas très bien pourquoi vous souhaitez ajouter un attribut à un seul Edge. Vous pouvez au contraire ajouter un attribut à tous les bords, puis vous donnez le the wanted value à votre Edge spécifique.

Networkx a une méthode appelée set_Edge_attributes peut ajouter un attribut Edge à tous les bords, par exemple

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

Sortie: 2.0

1
Xin-Feng Li

En fait, il existe un moyen plus rapide et plus efficace d’ajouter de nouveaux attributs à un Edge existant dans un graphique:

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