Интерфейс между networkx и igraph

Я работаю с networkx уже довольно давно, и он довольно хорошо служил моим целям с минимальными настройками до недавнего времени, когда я начал изучать обнаружение сообщества. Для сравнения, пакет Python igraph, похоже, имеет гораздо более широкую реализацию методов обнаружения сообщества (даже по сравнению с networkx с добавленным пакетом сообщества Thomas Aynaud). Мне просто интересно, есть ли какой-либо существующий протестированный API, который позволил бы легко преобразовать граф networkx в структуру igraph, чтобы я мог воспользоваться мощным igraph, предоставляемым в этой области?

Мы высоко ценим ваши добрые ответы.


person Moses Xu    schedule 23.04.2014    source источник


Ответы (5)


Networkx и python-igraph поддерживают широкий спектр алгоритмов чтения / записи (networkx, python-igraph).

По крайней мере два формата (GML и pajek) кажутся общими между ними, хотя я не Я пробовал это.

person Andrew Walker    schedule 23.04.2014
comment
Спасибо, Андрей, за быстрый ответ. Оказалось, что восстановить только топологические структуры графа NetwrokX в iGraph довольно тривиально - сложным моментом были атрибуты узла и ребра. Но этого хватило бы для обнаружения сообществом :) - person Moses Xu; 28.04.2014

Вот два способа преобразовать граф 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).

person Ulrich Stern    schedule 22.08.2016
comment
Этот ответ можно обновить для Python 3. zip больше не поддерживает индексирование. - person Arya McCarthy; 19.04.2017
comment
@AryaMcCarthy, готово. Я с удовольствием использовал Python 2, но в последнее время столкнулся с некоторыми пакетами, которые полностью поддерживались только для Python 3, так что пришло время подготовиться к переходу. :) - person Ulrich Stern; 11.12.2018

Поскольку я пытаюсь сохранить имена узлов / ребер как на 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())

И наоборот, если G, объект nx, задан, но нужен объект igraph:

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())

(также размещено здесь)

person Ebrahim Byagowi    schedule 16.07.2017

Рядом с GML и Pajek вот как я перенес свой график с помощью GraphML. Edgelist также работает, но имеет главный недостаток, заключающийся в том, что он отбрасывает идентификаторы узлов.

Я экспортировал свой неориентированный график с помощью R - iGraph (см. Аналогичную функцию в python igraph)

write_graph(igraphNetwork, exportFilePath, format = "graphml") с параметром exportFilePath, например папка / yournetwork.graphml

И импортируем через python - networkX и меняем метку по имени атрибута узла:

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

Таким образом я сохранил идентификаторы узлов.

person Simon Stolz    schedule 10.01.2019

Теперь это так просто, как

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

Документацию для from_networkx() можно найти здесь, а исходный код для его реализация здесь.

person rlchqrd    schedule 14.09.2020