Interface between networkx and igraph
I've been working with networkx for quite some time now and until recently I was working with my goals with minimal settings when I started looking into community discovery. By comparison, the igraph Python package seems to have much broader implementations of community discovery techniques (even compared to networkx with the addition of Thomas Aynaud's community package). I'm just wondering if there is any existing proven API out there that would make it easier to port a networkx graph into an igraph structure so I can take advantage of igraph's capabilities in this area?
Your kind responses are greatly appreciated.
source to share
Networkx and python-igraph support a wide range of read / write algorithms ( networkx , python-igraph ).
At least two formats ( GML and pajek) seem to be common between them, although I haven't tried that.
source to share
Here are two ways to convert NetworkX graph to 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 edge list was slightly faster for the following 2500 node graph on my machine: (Note that the code below is for Python 2 only; I've updated the above code 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)
.
source to share
As I am trying to store the node / edge names on both igraph or nx, this is my single layer version that also carries the node names when passed from the 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 path, if G, an nx object, is given, but an igraph object is needed:
g = igraph.Graph.TupleList(G.edges(), directed=True)
Of course, this is not a complete transfer like the other node attributes, and there is no transfer of edge attributes, but I hope this will be useful if you don't have them.
A more verbose version where you have more control over the transfer, 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()])
Nx to igraph:
g = igraph.Graph(directed=True) g.add_vertices(G.nodes()) g.add_edges(G.edges())
(also posted here )
source to share
Alongside GML and Pajek, this is how I transferred my graph using GraphML. Edgelist also works, but has the main disadvantage that it discards node IDs.
I exported my undirected graph using R - iGraph (see similar function in python igraph)
write_graph(igraphNetwork, exportFilePath, format = "graphml")
with exportFilePath like "folder / yournetwork.graphml"
And import via python - networkX and iterate over 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 have kept the node IDs.
source to share