Давайте добавим префиксы к этим индексам и столбцам и используем их в качестве узлов, чтобы легче было связать соединения:
print(df)
movie_1 movie_2 movie_3 movie_4 movie_5 movie_6
user_1 1.0 1.0 1.0 1.0 0.0 0.0
user_2 1.0 0.0 0.0 0.0 0.0 0.0
user_3 0.0 1.0 0.0 0.0 0.0 1.0
user_4 1.0 0.0 1.0 0.0 1.0 0.0
Для получения ребер ( и оставьте имена узлов ), мы могли бы использовать pandas, чтобы немного преобразовать данные. Мы можем получить MultiIndex
, используя stack
, а затем индексировать значения 1
. Затем мы можем использовать add_edges_from
, чтобы добавить все данные edge
:
B = nx.Graph()
B.add_nodes_from(df.index, bipartite=0)
B.add_nodes_from(df.columns, bipartite=1)
s = df.stack()
B.add_edges_from(s[s==1].index)
Мы можно использовать bipartite_layout
для удобного расположения двудольного графа:
top = nx.bipartite.sets(B)[0]
pos = nx.bipartite_layout(B, top)
nx.draw(B, pos=pos,
node_color='lightgreen',
node_size=2500,
with_labels=True)
Обратите внимание, что вполне вероятно, что эти очень разреженные матрицы приводят к несвязным графам, то есть графам, в которых не все узлы связаны с каким-либо другим узлом, и попытка получить оба набора вызовет ошибку, указанную здесь .
AmbiguousSolution - Возникает, если входной двудольный граф отключен, и не предоставлен контейнер со всеми узлами в одном двудольном наборе. При определении узлов в каждом двудольном наборе возможно более одного допустимого решения, если входной граф отключен.
В этом случае вы можете просто построить график как обычный с:
rcParams['figure.figsize'] = 10 ,8
nx.draw(B,
node_color='lightgreen',
node_size=2000,
with_labels=True)