Визуализация двудольного сетевого графика, созданного с использованием pandas кадра данных - PullRequest
2 голосов
/ 06 февраля 2020

У меня есть данные в CSV-файле, и я читаю их через pandas, как показано ниже

import networkx as nx
import pandas as pd
import matplotlib.pyplot as plt

sub_data = pd.read_csv('sample.csv')

Вывод:

   user_id   item_id    rating

0    772          36     3
1    471         228     5
2    641         401     4
3    312          98     4
4     58         504     5

Создание сетевого графика с использованием этих данных:

 edges = [tuple(x) for x in sub_data[['user_id','item_id']].values.tolist()]
 B = nx.Graph()
 B.add_nodes_from(sub_data['user_id'].unique(), bipartite=0, label='user')
 B.add_nodes_from(sub_data['item_id'].unique(), bipartite=1, label='item')
 B.add_edges_from(edges, label='rating')    

Построение графика с использованием приведенного ниже кода:

pos=nx.spring_layout(B)
nx.draw(B,pos,node_color='#A0CBE2',edge_color='#00bb5e',width=1,
     edge_cmap=plt.cm.Blues,with_labels=True) 

Я получаю такой график: enter image description here

Я получаю только узлы. где в я требую подключения узлов и оценки в качестве метки для этого соединения

1 Ответ

1 голос
/ 06 февраля 2020

Я попытался запустить код, который вы написали, я смог получить двудольный граф. В вашем случае я предполагаю, что NetworkX способен отображать двудольный граф, аналогичный моему, но поскольку у вашего графа больше узлов, ребра не видны должным образом. Примерно так

Original Graph

Вы можете видеть, что края едва видны. Если вы также ограничите число узлов до 10, вы также можете увидеть края. Если вы заинтересованы в воспроизведении примера, вот пример данных CSV (я добавил еще несколько точек к данным, представленным в вопросе):

,user_id,item_id,rating
0,772,36,3
1,471,228,5
2,641,401,4
3,312,98,4
4,58,504,5
5,67,98,4
6,471,229,3

Теперь я понимаю, что вы хотите увидеть график в двухстороннем макете, с двумя наборами узлов с каждой стороны. Вам нужно использовать bipartite_layout вместо spring_layout для достижения этой цели.

Вот полный код:

import networkx as nx
import pandas as pd
import matplotlib.pyplot as plt

sub_data = pd.read_csv('sample.csv')

edges = [tuple(x) for x in sub_data[['user_id','item_id']].values.tolist()]
B = nx.Graph()
B.add_nodes_from(sub_data['user_id'].unique(), bipartite=0, label='user')
B.add_nodes_from(sub_data['item_id'].unique(), bipartite=1, label='item')
B.add_edges_from(edges, label='rating')

# Now instead of spring_layout, use bipartite_layout

# First specify the nodes you want on left or top
left_or_top = sub_data['user_id'].unique()

# Then create a bipartite layout
pos = nx.bipartite_layout(B, left_or_top)

# Pass that layout to nx.draw
nx.draw(B,pos,node_color='#A0CBE2',edge_color='#00bb5e',width=1,
     edge_cmap=plt.cm.Blues,with_labels=True)

Bipartite New

Также обратите внимание, что я явно передал один набор узлов в bipartite_layout вместо использования bipartite_sets , как упоминалось здесь , потому что ваш график может быть отключен, и это приведет к AmbiguousSolution Error . Для получения дополнительной информации прочитайте документацию здесь и здесь .

Вы также можете просмотреть полный код в этом Google Colab Notebook .

Обновление : Если вы хотите показать края, вам нужно назначить их следующим образом (Ваш код для добавления оценок был неверным)

# Extract the ratings while extracting the edges from DF
edges = [tuple(x) for x in sub_data[['user_id','item_id', 'rating']].values.tolist()]

B = nx.Graph()

B.add_nodes_from(sub_data['user_id'].unique(), bipartite=0, label='user')
B.add_nodes_from(sub_data['item_id'].unique(), bipartite=1, label='item')

# Now assign the ratings correctly to edges
for row in edges:
    B.add_edge(row[0], row[1], rating=row[2])

Теперь нарисуйте край этикетки с использованием draw_netwokrx_edge_labels :

left_or_top = sub_data['user_id'].unique()
pos = nx.bipartite_layout(B, left_or_top)

# Draw the graph
nx.draw(B,pos,node_color='#A0CBE2',edge_color='#00bb5e',width=1,
     edge_cmap=plt.cm.Blues,with_labels=True)

# Get the edge labels for ratings
edge_labels = nx.get_edge_attributes(B,'rating')

# Draw the edge labels
nx.draw_networkx_edge_labels(B, pos, edge_labels=edge_labels)

Bipartite with edge labels

Ссылки:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...