如何在scipy中读取稀疏的有向图

时间:2013-07-28 15:52:54

标签: python graph scipy

我有一个稀疏加权有向图,表示在一个文件中,每行格式为

  

从重量

我想把它读成scipy的压缩稀疏格式,这样我就可以在它上面执行简单的遍历和图形算法(或者实际上是任何内存有效的表示)。但是,给定一个节点我希望能够快速按重量顺序列出其所有传出边缘,而无需每次都对它们进行排序。当然可以对每一个进行排序。

是否可以在scipy或使用任何其他python包中执行此操作?

1 个答案:

答案 0 :(得分:2)

您可以使用以下内容加载数据:

import numpy as np
import scipy.sparse as sps

data = np.genfromtxt('data.txt', dtype=[('from', np.intp),
                                        ('to', np.intp),
                                        ('weight', np.float)])

如果您想将权重存储在稀疏矩阵graph中,其中graph[i, j]是从节点i到节点j的权重,您可以这样做:

graph = sps.csr_matrix((data['weight'], (data['from'], data['to'])))

要获得传出节点的排序列表,我会使用字典,其中sorted_to是按权重排序的传出节点数组。它有点hacky,依赖于CSR稀疏矩阵格式,但您可以这样做:

graph = sps.rand(10, 10, density=0.1, format='csr')
data, indptr, indices = graph.data, graph.indptr, graph.indices
non_empty_rows, = np.nonzero(np.diff(graph.indptr))
sorted_out = {}
for j in non_empty_rows:
    weight_slice = data[indptr[j]:indptr[j+1]]
    out_slice = indices[indptr[j]:indptr[j+1]]
    sorted_out[j] = out_slice[np.argsort(weight_slice)]

用一个简单的例子:

>>> graph = sps.rand(5, 5, density=0.2, format='csr')
>>> graph.toarray()
array([[ 0.88968871,  0.        ,  0.        ,  0.80773932,  0.        ],
       [ 0.        ,  0.        ,  0.8921645 ,  0.        ,  0.        ],
       [ 0.        ,  0.        ,  0.        ,  0.        ,  0.        ],
       [ 0.18552664,  0.        ,  0.        ,  0.        ,  0.        ],
       [ 0.        ,  0.        ,  0.        ,  0.        ,  0.22945956]])
>>> non_empty_rows
array([0, 1, 3, 4], dtype=int64)
>>> sorted_out
{0: array([3, 0]), 1: array([2]), 3: array([0]), 4: array([4])}