我正在处理一个Networkx
.MultiDiGraph()
个对象,该对象由总共82927个定向电子邮件数据构建。在当前阶段,我试图从.MultiDiGraph()
对象及其相应的子图中获取最大的强连接组件。
可以访问文本数据here。
这是我的工作代码:
import networkx as nx
import pandas as pd
import matplotlib.pyplot as plt
email_df = pd.read_csv('email_network.txt', delimiter = '->')
edge_groups = email_df.groupby(["#Sender", "Recipient"], as_index=False).count().rename(columns={"time":"weight"})
email = nx.from_pandas_dataframe(edge_groups, '#Sender', 'Recipient', edge_attr = 'weight')
G = nx.MultiDiGraph()
G.add_edges_from(email.edges(data=True))
# G is a .MultiDiGraph object
# using .strongly_connected_components() to get the part of G that has the most nodes
# using list comprehension
number_of_nodes = [len(n) for n in sorted(nx.strongly_connected_components(G))]
number_of_nodes
# 'number_of_nodes' return a list of [1, 1, 1,...,1] of length 167 (which is the exact number of nodes in the network)
# using the recommended method in networkx documentation
largest = max(nx.strongly_connected_components(G), key=len)
largest
# 'largest' returns {92}, not sure what this means...
正如我在上面的代码块中所提到的,列表推导方法返回长度为167的[1,1,1,...,1]列表(这是我数据中节点的总数),而max(nx.strongly_connected_components(G), key=len)
返回{92}
,我不确定这意味着什么。
我的代码看起来有问题,我可能错过了处理数据的几个关键步骤。有人可以关注这个并启发我吗?
谢谢。
注意:修改后的代码(对Eric和Joel的称赞)
import networkx as nx
import pandas as pd
import matplotlib.pyplot as plt
email_df = pd.read_csv('email_network.txt', delimiter = ' ')
edge_groups = email_df.groupby(["#Sender", "Recipient"], as_index=False).count().rename(columns={"time":"weight"})
# per @Joel's comment, adding 'create_using = nx.DiGraph()'
email = nx.from_pandas_dataframe(edge_groups, '#Sender', 'Recipient', edge_attr = 'weight', create_using = nx.DiGraph())
# adding this 'directed' edge list to .MultiDiGraph() object
G = nx.MultiDiGraph()
G.add_edges_from(email.edges(data=True))
我们现在检查该网络中最大的强连通组件(就节点数而言)。
In [1]: largest = max(nx.strongly_connected_components(G), key=len)
In [2]: len(largest)
Out [2]: 126
最大的强连通组件由126个节点组成。
[更新]
在进一步试验和错误后,我发现在将数据加载到create_using = .MultiDiGraph()
时需要使用.DiGraph()
(而不是networkx
),否则,即使您获得了正确的节点数量{ {1}}及其弱/强连接的子图,你可能仍然得到错误的边数!这将反映在MultiDiGraph
输出中。
对于我的情况,我会建议其他人使用这个单行
.strongly_connected_subgraphs()
我们可以实施import networkx as nx
import pandas as pd
import matplotlib.pyplot as plt
G = nx.read_edgelist(path="email_network.txt", data=[('time', int)], create_using=nx.MultiDiGraph(), nodetype=str)
和.strongly_connected_components(G)
来验证。
如果您使用第一个代码块中的strongly_connected_subgraphs
输出networkx
,G
将提供126个节点和52xx边缘的输出,但如果您应用单行I如上所列,您将获得:
max(nx.strongly_connected_components(G), key=len)
由于与不同In [1]: largest = max(nx.strongly_connected_components(G), key=len)
In [2]: G_sc = max(nx.strongly_connected_subgraphs(G), key=len)
In [3]: nx.number_of_nodes(G_sc)
Out [3]: 126
In [4]: nx.number_of_nodes(G_sc)
Out [4]: 82130
图类关联的计数机制不同,您将获得两种方法相同数量的节点但边数不同。
答案 0 :(得分:3)
错误的根本原因是nx.from_pandas_dataframe
默认创建无向图。所以email
是一个无向图。然后,当您创建有向图时,每条边只出现在一个方向上。
要修复此问题,请使用带有参数nx.from_pandas_dataframe
create_using = DiGraph
与您获得的输出相关的旧评论
所有强关联组件都有一个节点。
执行max(nx.strongly_connected_components(G), key=len)
时,它会找到长度最长的节点集并将其返回。在你的情况下,它们都有长度1,所以它返回其中一个(我相信哪个networkx碰巧先放入nx.strongly_connected_components(G)
)。但它返回集,而不是长度。所以{92}
是它返回的节点集。
在{92}
中,nx.strongly_connected_components(G)
选择max([{1}, {3}, {5}], key = len)
> {1}
作为决胜局的/dev/xvdb1: UUID="5950368c-7bf0-45f6-a2b7-d53d3f3bcfa7" TYPE="ext4"
组成部分。
示例:
export GEM_HOME=~/.gems
export PATH=$GEM_HOME/bin:$PATH
gem install cocoapods
答案 1 :(得分:1)
[1, 1, 1,...,1] of length 167 (which is the exact number of nodes in the network)
这意味着图表中基本上没有strongly connected component(单独的顶点除外)。
如果按长度对这些组件进行排序,则会获得单个顶点的randon组件,因为组件都具有相同的长度(1
)。在您的示例中,{92}
,可能是任何其他顶点。
导入看起来是正确的,并且实际上没有强连接组件,这意味着没有人回复任何电子邮件。
要检查问题是否来自pandas
,MultiDiGraph
或您的导入,我写道:
G = nx.DiGraph()
with open('email_network.txt') as f:
for line in f:
n1, n2, time = line.split()
if n1.isdigit():
G.add_edge(int(n1),int(n2))
它没有改变结果。
只需添加G.add_edge(2,1)
边缘即可创建一个较大的强连接组件:
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 126, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 115, 117, 118, 119, 120, 121, 122, 123, 124, 128, 129, 134, 149, 151}