Interface between networkx and igraph

。_饼干妹妹 提交于 2019-12-03 11:18:58

Networkx and python-igraph both support a wide range of read/write algorithms (networkx, python-igraph).

At least two formats (GML and pajek) appear to be common between the two, although I haven't tried this.

Here two ways to convert a NetworkX graph to an 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()

Using the edge list was somewhat faster for the following 2500-node graph on my machine: (Note that the code below is Python 2 only; I updated the code above to be Python 2/3 compatible.)

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

Using the edge list was also somewhat faster for g = nx.complete_graph(2500).

As I try to store names of nodes/edges on both igraph or nx, this is my one-liner version which also transfers nodes names while transferring from igraph object, g, to 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())

And the reverse way if G, a nx object, is given but an igraph object is needed:

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

Of course these are not complete transfer as other node attributes and also edge attribute transfers are missing but I hope would be useful when you don't have them.


More verbose version that you have more control while transferring, from igraph to 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()])

From nx to igraph:

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

(also posted here)

Next to GML, and Pajek, here is how I transported my graph using GraphML. Edgelist works as well, but has the main distadvantage that it discards node identifiers.

I exported my undirected graph using R - iGraph (see similar function in python igraph)

write_graph(igraphNetwork, exportFilePath, format = "graphml") with exportFilePath being e.g. "folder/yournetwork.graphml"

And import via python - networkX and relabel by node attribute name: import networkx as nx G = nx.read_graphml(exportFilePath) G = nx.relabel_nodes(G, nx.get_node_attributes(G, 'name'))

This way I kept the node identifiers.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!