J'ai un dataframe Pandas avec deux colonnes d'un type différent, par exemple J'ai créé un graphe NetworkX à l'aide de la méthode de_pandas_dataframe et peut réussir à le tracer visuellement. Il montre chaque nœud et chaque relation entre ceux qui étaient des utilisateurs et ceux qui étaient des ordinateurs comme un bord. P> Ce que je suis vraiment intéressé, est la relation entre les utilisateurs. C'est à dire. Dans l'exemple, l'utilisateur 1 est lié à l'utilisateur 3 car ils ont tous deux un ordinateur en commun. Je voudrais un moyen de refactoriser mon graphique pour afficher uniquement les utilisateurs en tant que nœuds et d'avoir les ordinateurs comme des bords qui connectent les deux utilisateurs (noter que je n'ai pas à conserver les données de quel ordinateur forme le bord bien que ce serait sois gentil). P> J'ai essayé certaines jointures de soi, mais la sortie n'a pas vraiment fonctionné comment je voulais: p> dans l'exemple ci-dessus, je suis Ne pas obtenir la paire annonce même si les deux sont associés à l'ordinateur 1. P> Quelle est la meilleure façon de y parvenir? Devrait-il s'agir de manipuler les données de Pandas pour montrer à ces couples entre les utilisateurs seulement? Si c'est le cas, comment? Ou devrais-je le faire via NetworkX? P> P>
3 Réponses :
Si je comprends votre question correctement, vous souhaitez convertir votre graphique en un ensemble de sous-graphiques entièrement connectés dont les nœuds sont les utilisateurs.
Répétition de votre code: P>
import itertools # collect all connection nodes connecting_nodes = [n for n in G.nodes if str(n).isdigit()] edgelist = [] for cn in connecting_nodes: # create all combinations of adjacent nodes and store in list of tuples edgelist += itertools.combinations(G.neighbors(cn), 2) #remove positional information edgelist = [tuple(sorted(list(set(a)))) for a in edgelist] from collections import Counter # now count occurences of each tuple (= number of "independent connections" # between two non-digit nodes). # Counter(edgelist) returns a dict, i.e. {('a', 'b'): 2, ...}, # which can be unpacked like so: weighted_edges = [(*u, v) for u,v in Counter(edgelist).items()] # now make new graph with non-digit nodes and add weighted edges: H = nx.Graph() H.add_nodes_from([n for n in G.nodes if not str(n).isdigit()]) H.add_weighted_edges_from(weighted_edges) # and draw, with width proportional to weight pos = nx.spring_layout(H) weights = [e[2]['weight'] for e in H.edges(data=True)] nx.draw_networkx(H, pos, width=weights)
C'est très slick. Pour compliquer encore les choses, comment pourrais-je utiliser la valeur des «nœuds de connexion rouge» comme valeur associée aux bords qui connectent maintenant les nœuds bleus? par exemple. Existe-t-il un moyen de sorte que si deux "utilisateurs" étaient liés par un nombre élevé d'ordinateurs ", je pourrais épaissir la ligne de connexion?
C'est vraiment cool. Des recommandations sur les endroits où en savoir plus sur ce type de choses?
J'aime bien les choses déconcertantes, alors je n'ai pas de connaissances officielles sur ce type d'analyse. Pour des connaissances formelles, j'essaierais de trouver un cours ou un manuel sur l'analyse du réseau ou la théorie des graphes.
Personnellement, je pense que l'utilisation d'une jointure interne sur la base de données est effectivement plus propre que d'utiliser une opération de graphique. Dans Pandas, la jointure peut être exécutée en tant que telle: Vous pouvez ensuite utiliser la liste des bords pour créer un graphique NetworkX graphique code>. p> p>
Merci pour cela, c'est aussi une excellente solution. Je vais rester avec l'option graphique car je pourrai peut-être construire dans d'autres détails de ces objets «Edge» comme un «bon à avoir» au fil du temps.
Quelle est la taille de ce graphique? De très grandes opérations devraient avoir lieu dans des pandas si vous le pouvez, car cela sera sensiblement plus rapide (même dans de nombreux cas, d'exécuter un algorithme plus complexe). Mais pour quelques milliers de lignes, un algorithme NetworkX sera probablement plus facile à écrire et à entretenir.
Je pense que ce que vous regardez est une projection bipartite. NetworkX.github.io/ Documentation / Dernières / Référence / Algorithmes / ...
Ce ne sera pas grand, surtout probable moins de 1k nœuds
Cela a l'air assez compliqué mais je vais jeter un coup d'œil. J'ai aussi joué avec des jointures de soi mais que cela n'a pas encore travaillé non plus non plus. Je suis heureux de perdre les données de bord si je peux facilement créer un fichier de données de juste utilisateur à des paires d'utilisateurs qui reflètent ce qui précède.
Je ne pense pas que le bipartite est ce que je veux. C'est plus approprié si je voulais garder à la fois mes utilisateurs et mes ordinateurs en tant que nœuds. Je veux me débarrasser des ordinateurs en tant que nœuds et je n'ai que des utilisateurs.
Vous décrivez exactement les commandes bipartites_projection.