我有一个稀疏加权有向图,表示在一个文件中,每行格式为
从重量
我想把它读成scipy的压缩稀疏格式,这样我就可以在它上面执行简单的遍历和图形算法(或者实际上是任何内存有效的表示)。但是,给定一个节点我希望能够快速按重量顺序列出其所有传出边缘,而无需每次都对它们进行排序。当然可以对每一个进行排序。
是否可以在scipy或使用任何其他python包中执行此操作?
答案 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])}