网络x和igraph之间的接口

19

我已经使用networkx相当长的时间了,它一直以来都能够在很少的调整下满足我的需求,直到最近我开始研究社区检测。与之相比,igraph Python软件包似乎具有更广泛的社区检测方法实现(即使与添加了Thomas Aynaud的community软件包的networkx相比也是如此)。我想知道是否存在已经存在且经过测试的API,可以将networkx图形容易地转换为igraph结构,这样我就可以利用igraph在这个领域提供的功能了吗?

非常感谢您的答复。

5个回答

14

这里有两种将NetworkX图转换为igraph的方法:

import networkx as nx, igraph as ig

# create sample NetworkX graph
g = nx.planted_partition_graph(5, 5, 0.9, 0.1, seed=3)

# convert via edge list
g1 = ig.Graph(len(g), list(zip(*list(zip(*nx.to_edgelist(g)))[:2])))
  # nx.to_edgelist(g) returns [(0, 1, {}), (0, 2, {}), ...], which is turned
  #  into [(0, 1), (0, 2), ...] for igraph

# convert via adjacency matrix
g2 = ig.Graph.Adjacency((nx.to_numpy_matrix(g) > 0).tolist())

assert g1.get_adjacency() == g2.get_adjacency()

在我的机器上,使用边缘列表对以下2500个节点的图表现出了略微更快的速度:(请注意,下面的代码仅适用于Python 2;我已更新上面的代码以与Python 2/3兼容。)

In [5]: g = nx.planted_partition_graph(50, 50, 0.9, 0.1, seed=3)

In [6]: %timeit ig.Graph(len(g), zip(*zip(*nx.to_edgelist(g))[:2]))
1 loops, best of 3: 264 ms per loop

In [7]: %timeit ig.Graph.Adjacency((nx.to_numpy_matrix(g) > 0).tolist())
1 loops, best of 3: 496 ms per loop

对于g = nx.complete_graph(2500),使用边列表也略快一些。


5
这个回答可能需要更新适用于Python 3。zip不再支持下标访问。 - Arya McCarthy
@AryaMcCarthy,已完成。我一直很喜欢使用Python 2,但最近遇到了一些只支持Python 3的包,所以是时候准备切换了。 :) - Ulrich Stern

6

Networkx和python-igraph都支持广泛的读写算法(networkx, python-igraph)。

至少有两种格式(GML和Pajek)在两者之间是常见的,尽管我没有尝试过。


感谢Andrew的快速回答。事实证明,在iGraph中仅重建NetwrokX图的拓扑结构相当简单 - 难点在于节点和边缘属性。但这已足以进行社区检测 :) - Moses Xu

5

当我尝试在igraph或nx上存储节点/边缘的名称时,这是我的一行代码版本,它在从igraph对象g转移时也传输节点名称到nx:

G = nx.from_edgelist([(names[x[0]], names[x[1]])
                      for names in [g.vs['name']] # simply a let
                      for x in g.get_edgelist()], nx.DiGraph())

如果需要 igraph 对象,但只有 G(nx 对象)可用,则需要反过来进行转换:

g = igraph.Graph.TupleList(G.edges(), directed=True)

当然,这些并不完全转移,因为其他节点属性和边缘属性转移也遗漏了,但我希望在您没有它们的情况下会有用。
更详细的版本可以让您在从igraph到nx的传输过程中更加掌控:
G = nx.DiGraph()
names = g.vs['name']
G.add_nodes_from(names)
G.add_edges_from([(names[x[0]], (names[x[1]])) for x in g.get_edgelist()])

从nx到igraph:

g = igraph.Graph(directed=True)
g.add_vertices(G.nodes())
g.add_edges(G.edges())

(也在这里发布了)
请问需要翻译的具体内容是什么?

4

现在这很容易了

import igraph
g = igraph.Graph.from_networkx(G)

from_networkx() 的文档可以在 这里 找到,其实现的源代码可以在 这里 找到。


4

在使用 GMLPajek之后,我使用 GraphML 将我的图形转移了过来。

EdgeList 也可以,但其主要缺点是丢弃了节点标识符。

我使用 R - iGraph(在 Python igraph 中有类似的函数)导出了我的无向图:

write_graph(igraphNetwork, exportFilePath, format = "graphml") 其中,exportFilePath 可以为 "folder/yournetwork.graphml" 等路径。

然后,通过 Python - NetworkX 进行导入,并按节点属性名重新标记:

import networkx as nx
G = nx.read_graphml(exportFilePath)
G = nx.relabel_nodes(G, nx.get_node_attributes(G, 'name'))

我保留了节点标识符来实现这种方式。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接