2017-07-02 150 views
1

在处理大型SciPy CSR稀疏矩阵时,我注意到对矩阵进行切片以从矩阵中获取单行非常慢,因为它似乎会进行复制。快速访问的稀疏矩阵

有什么办法可以制作一个稀疏矩阵,而不是复制它的现有行的引用,也许有比CSR矩阵更适合的实现吗?

我的实现需要快速查找元素和行,并快速查找矢量的所有非零索引。我从来不需要以任何方式改变矩阵或在矩阵上执行其他操作。

回答

0

你可以采取CSR表示的优点直接切片底层阵列和共享新的CSR矩阵中的数据:

mat = # some CSR matrix 
i = # the index of whatever row you want 
start, stop = mat.indptr[i], mat.indptr[i+1] 
noncopy_row_i = scipy.sparse.csr_matrix((mat.data[start:stop], 
             mat.indices[start:stop], 
             numpy.array([0, stop-start])), 
             shape=(1, mat.shape[1])) 
+0

我用'mat [我,:]'测试了你的函数。时序为69.3μs×107μs,这是一个适度的改进。在“lil”格式上索引为78μs。 – hpaulj

+0

如果你使用你的代码只返回'data'和'indices',而不是构造一个新的'csr_matrix',它会快得多,大约2μs。提取'lil'格式的'row'元素时适用同样的加速。 – hpaulj

+0

我决定这样做,只使用索引而不构建新的csr_matrix。管理让我的算法运行在10微秒左右,而不是总共1毫秒,这些优化已经够好了,谢谢你们两位! :-) – mahboi

0

numpy的支持不同类型的OS sparces矩阵:https://docs.scipy.org/doc/scipy/reference/sparse.html#usage-information

可能coo_matrix将提供更快速的元素查找,但是您也可以在其他操作中放弃。我认为最好的方法是对你的数据和algorythms进行基准测试。

+0

'coo'格式不执行索引。 – hpaulj

+0

如果您需要非零元素,则有一个特殊的“非零”方法 - https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.coo_matrix.nonzero.html#scipy.sparse.coo_matrix.nonzero –

+0

稀疏的非零方法本质上返回'coo'格式的'row'和'col'属性。检查它的源代码。 – hpaulj