在Scipy中切片稀疏矩阵 - 哪种类型最好?

gab*_*abe 26 python indexing scipy sparse-matrix slice

SciPy 稀疏矩阵教程非常好 - 但它实际上留下了切片un(der)开发的部分(仍然是大纲形式 - 参见章节:"处理稀疏矩阵").

一旦这个问题得到解答,我会尝试更新教程.

我有一个大的稀疏矩阵 - 目前采用dok_matrix格式.

import numpy as np
from scipy import sparse
M = sparse.dok_matrix((10**6, 10**6))
Run Code Online (Sandbox Code Playgroud)

对于各种方法,我希望能够切割列,而对于其他我希望切片行.理想情况下,我会使用高级索引(即布尔向量bool_vect)来对稀疏矩阵进行切片M- 如下所示:

bool_vect = np.arange(10**6)%2  # every even index
out = M[bool_vect,:]            # Want to select every even row
Run Code Online (Sandbox Code Playgroud)

要么

out = M[:,bool_vect] # Want to select every even column
Run Code Online (Sandbox Code Playgroud)

首先,dok_matrices不支持这个 - 但我认为如果我第一次转向lil_matrices,它会缓慢地工作 sparse.lil_matrix(M)

至于我可以从教程中收集 - 切片列我想使用CSC并切片行我想要切片CSR.那么这是否意味着我应该M通过以下方式投射矩阵:

M.tocsc()[:,bool_vect]
Run Code Online (Sandbox Code Playgroud)

要么

M.tocsr()[bool_vect,:]
Run Code Online (Sandbox Code Playgroud)

我有点猜测,因为它,我的代码很慢.任何了解其工作原理的人的帮助都会受到赞赏.提前致谢.

如果事实证明我不应该使用布尔数组索引我的矩阵,而是使用整数(索引)列表 - 这也是我很乐意找到的东西.哪个更有效率.

最后 - 这是一个很大的矩阵,如果这可以在广播中发生,那么奖励积分.

gab*_*abe 44

好的,所以我很确定这样做的"正确"方法是:如果要切片列,请使用tocsc()并使用整数列表/数组进行切片.布尔向量似乎没有使用稀疏矩阵 - 它在numpy中使用ndarrays的方式.这意味着答案是.

indices = np.where(bool_vect)[0]
out1 = M.tocsc()[:,indices]
out2 = M.tocsr()[indices,:]
Run Code Online (Sandbox Code Playgroud)

但问题是:这是最好的方法吗?这是否到位?

在实践中,这似乎确实发生了 - 它比以前的尝试(使用lil_matrix)快得多.

  • 如果`M`是一种没有索引的格式(`coo`或`dok`),那么这种转换是正确的方式.但是如果`M`已经是`csr`切换到`csc`只是为了做列索引可能不值得.`稀疏`索引是一项复杂的业务. (3认同)