为何对Scipy稀疏CSR矩阵做列切片操作时会触发警告?
为什么修改CSR矩阵时会触发SparseEfficiencyWarning?
先来看你运行的这段代码:
import numpy as np from scipy import sparse dok = sparse.dok_matrix((5,1)) dok[1,0] = 1 data = np.array([0,1,2,3,4]) row = np.array([0,1,2,3,4]) col = np.array([0,1,2,3,4]) csr = sparse.csr_matrix((data, (row, col))) csr[:, 0] += dok
触发的警告内容是:
SparseEfficiencyWarning: Changing the sparsity structure of a csr_matrix is expensive. lil_matrix is more efficient.
核心原因拆解
咱们得先搞清楚CSR矩阵的设计定位——官方文档明确说它适合高效行切片、矩阵乘法这类读取/计算操作,但它天生不擅长修改稀疏结构(也就是新增原本不存在的非零元素)。
CSR的存储逻辑:CSR用三个数组
data、indices、indptr压缩存储非零元素。indptr记录每行非零元素在data和indices里的起止位置,indices存非零元素的列索引,data存对应的值。这种结构是为了快速读取和计算优化的,但要新增非零元素时,需要重新调整三个数组的长度和内容,比如插入元素到data和indices的指定位置,还要更新indptr的指针,这个过程需要移动大量数据,成本非常高。你的代码到底触发了什么:
- 初始的
csr是5×5的对角矩阵,第0列只有(0,0)位置有值(值为0); dok是5×1的矩阵,仅(1,0)位置有值1;- 执行
csr[:, 0] += dok时,会给csr的(1,0)位置新增一个非零元素(值为1),这就改变了CSR矩阵原本的稀疏结构——原本这个位置是零,现在变成非零了。
- 初始的
Scipy检测到你在做CSR矩阵不擅长的操作,就抛出这个警告,提醒你:如果需要频繁修改稀疏结构(新增/删除非零元素),用lil_matrix会更高效,因为它是基于链表的存储结构,动态修改元素的成本很低。
内容的提问来源于stack exchange,提问作者Federico Caccia
相关产品推荐
相关产品推荐

