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

Posted

技术标签:

【中文标题】在 Scipy 中切片稀疏矩阵——哪种类型效果最好?【英文标题】:Slicing Sparse Matrices in Scipy -- Which Types Work Best? 【发布时间】:2012-11-01 09:10:36 【问题描述】:

SciPy Sparse Matrix tutorial 非常好——但它实际上留下了未开发的切片部分(仍处于大纲形式——参见“处理稀疏矩阵”部分)。

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

我有一个大的稀疏矩阵——目前是 dok_matrix 格式。

import numpy as np
from scipy import sparse
M = sparse.dok_matrix((10**6, 10**6))

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

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

out = M[:,bool_vect] # Want to select every even column

首先,dok_matrices 不支持这一点——但我认为如果我首先通过sparse.lil_matrix(M) 转换为 lil_matrices,它会(缓慢)工作

据我从教程中收集到的信息,我想使用 CSC 对列进行切片,对我想对 CSR 进行切片的行。那么这是否意味着我应该通过以下方式转换矩阵M

M.tocsc()[:,bool_vect]

M.tocsr()[bool_vect,:]

我在这里有点猜测,因此我的代码很慢。任何了解其工作原理的人的帮助将不胜感激。提前致谢。

如果事实证明我不应该用布尔数组索引我的矩阵,而是整数列表(索引)——这也是我很乐意发现的。哪个更有效。

最后——这是一个很大的矩阵,所以如果这可以发生在适当的位置/通过广播,那么可以加分。

【问题讨论】:

【参考方案1】:

好的,所以我很确定这样做的“正确”方法是: 如果要对列进行切片,请使用 tocsc() 并使用整数列表/数组进行切片。布尔向量似乎对稀疏矩阵不起作用——就像它在 numpy 中对 ndarray 所做的那样。这意味着答案是。

indices = np.where(bool_vect)[0]
out1 = M.tocsc()[:,indices]
out2 = M.tocsr()[indices,:]

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

在实践中,这似乎确实发生了——而且比之前的尝试(使用 lil_matrix)要快得多。

【讨论】:

如果M 是没有索引的格式(coodok),那么这种转换是正确的方法。但是如果 M 已经是 csr 切换到 csc 只是为了进行列索引可能不值得。 sparse 索引是一项复杂的业务。 我可以确认使用 csr 进行行切片会有很大的不同

以上是关于在 Scipy 中切片稀疏矩阵——哪种类型效果最好?的主要内容,如果未能解决你的问题,请参考以下文章

python中scipy学习——随机稀疏矩阵及操作

[使用Python,NumPy,SciPy使用矩阵乘法对矩阵进行有效切片

Scipy稀疏矩阵维度问题

scipy稀疏矩阵

如何将“SciPy 稀疏矩阵”转换为“NumPy 矩阵”?

计算 scipy 稀疏矩阵的稀疏传递闭包