有向图的最大强连通分量

时间:2017-09-20 08:20:33

标签: python networkx subgraph connected-components

我正在处理一个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输出networkxG将提供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图类关联的计数机制不同,您将获得两种方法相同数量的节点但边数不同。

2 个答案:

答案 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},可能是任何其他顶点。

导入看起来是正确的,并且实际上没有强连接组件,这意味着没有人回复任何电子邮件。

要检查问题是否来自pandasMultiDiGraph或您的导入,我写道:

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}