2016-12-20 3 views
0

J'essaye de créer un graphe de réseau en utilisant networkX auquel sont assignés les noeuds et les attributs. Chaque nœud est unique mais il peut avoir des attributs correspondants avec d'autres nœuds. Ces attributs agiront comme les arêtes entre les noeuds qui ont tous ce même attribut.NetworkX - Créer un graphe à partir d'un noeud et d'attributs

Un exemple de l'entrée (noeud et attributs)

Name1 2-s2.0-84905590088, 2-s2.0-84901477890 
Name2 2-s2.0-84941169876 
Name3 2-s2.0-84958012773 
Name4 2-s2.0-84960796474 
Name5 2-s2.0-84945302996, 2-s2.0-84953281823, 2-s2.0-84944268402, 2-s2.0-84949478621, 2-s2.0-84947281259, 2-s2.0-84947759580, 2-s2.0-84945265895, 2-s2.0-84945247800, 2-s2.0-84946541351, 2-s2.0-84946051072, 2-s2.0-84942573284, 2-s2.0-84942280140, 2-s2.0-84937715425, 2-s2.0-84943751990, 2-s2.0-84957729558, 2-s2.0-84938844501, 2-s2.0-84934761065 
Name6 2-s2.0-84908333808 
Name7 2-s2.0-84925879816 
Name8 2-s2.0-84940447040, 2-s2.0-84949534001 
Name9 2-s2.0-84899915556, 2-s2.0-84922392381, 2-s2.0-84905079505, 2-s2.0-84940931972, 2-s2.0-84893682063, 2-s2.0-84954285577, 2-s2.0-84934934228, 2-s2.0-84926624187 
Name10 2-s2.0-84907065810 

si Name5 aurait beaucoup de bords reliés à la hauteur des autres noms avec le même identifiant.

Je ne suis pas sûr si c'est l'idée derrière networkX ou si vous pouvez même utiliser ce genre d'entrée pour graver. Si cette méthode n'est pas réalisable, comment formaterais-je l'entrée pour créer ce graphique? Je n'ai pas pu trouver de documentation ou de vidéos sur l'utilisation de networkX de cette façon.

+0

Je ne pense pas qu'il existe une manière intégrée de faire cela avec NetworkX, mais vous pouvez certainement le faire en créant tous les nœuds, puis en itérant sur les "attributs" et en ajoutant les bords appropriés. – BrenBarn

Répondre

1

Ce que vous demandez est possible. J'ai stocké vos données dans un fichier csv - notez que j'ai ajouté un , après les noms de noeuds et que j'ai supprimé tous les espaces.

Name1,2-s2.0-84905590088,2-s2.0-84901477890 
Name2,2-s2.0-84941169876 
Name3,2-s2.0-84958012773 
Name4,2-s2.0-84960796474 
Name5,2-s2.0-84945302996,2-s2.0-84953281823,2-s2.0-84944268402,2-s2.0-84949478621,2-s2.0-84947281259,2-s2.0-84947759580,2-s2.0-84945265895,2-s2.0-84945247800,2-s2.0-84946541351,2-s2.0-84946051072,2-s2.0-84942573284,2-s2.0-84942280140,2-s2.0-84937715425,2-s2.0-84943751990,2-s2.0-84957729558,2-s2.0-84938844501,2-s2.0-84934761065 
Name6,2-s2.0-84908333808 
Name7,2-s2.0-84925879816 
Name8,2-s2.0-84940447040,2-s2.0-84949534001 
Name9,2-s2.0-84899915556,2-s2.0-84922392381,2-s2.0-84905079505,2-s2.0-84940931972,2-s2.0-84893682063,2-s2.0-84954285577,2-s2.0-84934934228,2-s2.0-84926624187 
Name10,2-s2.0-84907065810 

Une observation: vous dites que Name5 aurait beaucoup de bords, mais ses attributs sont uniques. De plus, lorsque je lance mon code avec vos données, il s'avère que tous les attributs sont uniques, donc il n'y a pas d'arêtes dans le graphique.

J'ai twitté vos données afin que j'utilise seulement les 12 premiers caractères de chaque attribut (je fais cela avec la ligne new_attributes = [x[:12] for x in new_attributes]). De cette façon, je reçois des attributs correspondants.

maintenant le code:

import networkx as nx 
import csv 

G = nx.Graph() 

with open('data.csv') as csvfile: 
     csv_reader = csv.reader(csvfile, delimiter=',') 
     for row in csv_reader: 

      new_node = row[0] # first element in row 
      new_attributes = row[1:] # whole row except the first element 
      new_attributes = [x[:12] for x in new_attributes] # remove this for your data! 
      # add the node and its attributes to the graph 
      G.add_node(new_node, my_attributes=new_attributes) # attributes are stored as a list 

      # add edges based on existing nodes 
      for node, attrs in G.nodes(data=True): 
       # skip node we just added 
       if node != new_node: 
        for attr in attrs['my_attributes']: 
         # check if any of the attributes for `node` are also in the `new_attributes` list 
         if attr in new_attributes: 
          G.add_edge(node, new_node) 

for edge in G.edges(): 
    print('EDGE:', edge, '| COMMON ATTRIBUTES:', set(G.node[edge[0]]['my_attributes']) & set(G.node[edge[1]]['my_attributes'])) 

Pour chaque ligne CSV ajouter un noeud (avec ses attributs) à la courbe et sur la base des noeuds de courant dans le graphique (et leurs attributs) ajouter les bords. Notez que les attributs de noeud sont stockés dans une liste et peuvent être accessibles avec la clé my_attributes. À la fin, j'imprime également les bords avec les attributs correspondants pour les nœuds dans un bord particulier (j'utilise set et & pour obtenir l'intersection de deux listes d'attributs).

sortie pour les données tweeked:

EDGE: ('Name5', 'Name9') | COMMON ATTRIBUTES: {'2-s2.0-84934'} 
EDGE: ('Name5', 'Name8') | COMMON ATTRIBUTES: {'2-s2.0-84949'} 
EDGE: ('Name8', 'Name9') | COMMON ATTRIBUTES: {'2-s2.0-84940'} 
EDGE: ('Name1', 'Name9') | COMMON ATTRIBUTES: {'2-s2.0-84905'} 

Une dernière remarque: si vous avez besoin d'avoir plusieurs arêtes entre deux noeuds utiliser un MultiGraph.

+0

Je vous remercie, Juste une question, de sorte que les données réelles ont le nom de famille, première initiale par ex. 'Smith, J'. Cela causerait un problème avec la séparation des noeuds et des 'attributs' – Sharw

+0

Vous pouvez choisir un autre délimiteur pour le fichier csv ou simplement mettre le nom du noeud entre guillemets doubles (par exemple '' Smith, J ''). – edo

+0

Ok doux, comment serait-il facile d'entrer ce résultat dans gephi pour obtenir une visualisation? – Sharw