我刚刚开始编码并试图了解 NetworkX 的工作原理。我有一个包含文档和主题列的 Pandas DataFrame。 topics
列表示每个文档(行)中是否存在主题。
df = pd.DataFrame({'DOC': ['Doc_A', 'Doc_B', 'Doc_C', 'Doc_D', 'Doc_E'], 'topic_A': [0,0,1,0,0], 'topic_B': [1,0,0,1,0], 'topic_C': [0,1,1,1,0]})
DOC topic_A topic_B topic_C
0 Doc_A 0 1 0
1 Doc_B 0 0 1
2 Doc_C 1 0 1
3 Doc_D 0 1 1
4 Doc_E 0 0 0
我想做的是创建网络,其中:
1)文档是节点,边是主题(没有权重),所以同一个节点有多个边。
2) 文档是节点,边是主题,但不是有多个边,而是根据它们共享的主题的数量对边进行加权。
我怎样才能做到这一点?我什至在这里思考正确吗?
最佳答案
以下是如何构建一个网络,其中文档中主题的共现表示为边:
首先使 DOC 成为索引并堆叠数据帧。您将获得表格的线性表示:
stacked = df.set_index('DOC').stack()
#DOC
#Doc_A topic_A 0
# topic_B 1
# topic_C 0
#...
当然,您只需要有 1 的行,因为 1 表示主题和文档是连接的:
stacked = stacked[stacked==1]
这个表的多索引其实就是一个边列表:
edges = stacked.index.tolist()
#[('Doc_A', 'topic_B'), ('Doc_B', 'topic_C'), ('Doc_C', 'topic_A'),
# ('Doc_C', 'topic_C'), ('Doc_D', 'topic_B'), ('Doc_D', 'topic_C')]
让我们用它制作一个网络。新图是二部图。您可以投影它以保留 topicx 但丢弃 documentx - 或者相反:
G = nx.Graph(edges)
Gp = nx.bipartite.project(G,df.set_index('DOC').columns)
# or
# nx.bipartite.project(G,df.set_index('DOC').index)
Gp.edges()
#EdgeView([('topic_A', 'topic_C'), ('topic_B', 'topic_C')])
后面跟着一个 shameless piece of self-promotion .
关于python - 从 Pandas DataFrame 创建 NetworkX 图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51639295/