小能豆

Graph.get_adjacency() 很慢,并且输出很奇怪

py

考虑python-igraph 0.7中的一个图对象G,如果我想要G的邻接矩阵A,我必须写A=G.get_adjacency(),但是有两个问题:

  1. 即使 G 是稀疏的,有 3000 个节点,在我的商用笔记本电脑上生成 A 也需要很长时间。创建邻接矩阵的代价可能这么高吗?
  2. 输出 A 是一个 Matrix 对象,因此如果我想使用 numpy 模块对 A 进行操作,我必须先在列表中转换它,然后在 numpy.matrix 中转换它。此外,如果 A 是稀疏的,我需要在稀疏 scipy 矩阵中进行第三次转换。

在 Igraph 中是否有任何方法可以在合理的时间内获取稀疏图的 scipy.sparse 矩阵?


阅读 17

收藏
2025-01-09

共1个答案

小能豆

  1. 图是否稀疏并不重要,因为 igraph 仍将创建一个密集矩阵,因此它是一个 O(n 2 ) 操作。(从技术上讲,矩阵本身是在 C 层创建的,其中将矩阵初始化为全零需要 O(n 2 ),然后在 O(m) 中用 1 填充,其中 n 是顶点数,m 是边数 - 但随后矩阵被转发到 Python 层,在那里它被转换为 Matrix 对象,而 Python 层不知道矩阵本质上是稀疏的,因此转换它需要 O(n 2 ),在我的笔记本电脑上,为一个有 3000 个节点的图创建邻接矩阵大约需要 500 毫秒,我认为这可能是正常的。

  2. 是的,有一种方法可以直接从 igraph 图创建稀疏矩阵,尽管它有点冗长:

```py
from scipy.sparse import coo_matrix
from numpy import hstack, ones

def graph_to_sparse_matrix(graph):
xs, ys = map(array, zip(*graph.get_edgelist()))
if not graph.is_directed():
xs, ys = hstack((xs, ys)).T, hstack((ys, xs)).T
else:
xs, ys = xs.T, ys.T
return coo_matrix((ones(xs.shape), (xs, ys)))
```

此版本在我的计算机上用约 26 毫秒的时间将相同的图转换为 SciPy 稀疏矩阵。

2025-01-09