CSR 是一种存储稀疏矩阵的高效格式,通过只存储非零元素来节省内存。它用三个数组来表示矩阵。
1. 三个核心数组
假设我们有一个稀疏矩阵:
[[1, 0, 0, 2],
[0, 3, 4, 0],
[5, 0, 0, 6]]
CSR 格式需要三个数组:
data 数组
存储所有非零元素的值,按行优先顺序排列:
data = [1, 2, 3, 4, 5, 6]
indices 数组
存储每个非零元素所在的列索引:
indices = [0, 3, 1, 2, 0, 3]
indptr 数组
行指针数组,长度为 行数 + 1,存储每行第一个非零元素在 data 中的起始位置:
indptr = [0, 2, 4, 6]
解释,
indptr[0] =0 指出第0行从 data[0] 开始
indptr[1] =2 指出第1行从 data[2] 开始
indptr[2] =4 指出第2行从 data[4] 开始
indptr[3] =6 指出结束位置,同时最后这个值也会等于元素个数。
2. 矩阵重建过程
通过三个数组可以完全恢复原矩阵:
-
第0行
data[indptr[0]:indptr[1]] = [1, 2],对应列indices[0:2] = [0, 3] -
第1行
data[indptr[1]:indptr[2]] = [3, 4],对应列indices[2:4] = [1, 2] -
第2行
data[indptr[2]:indptr[3]] = [5, 6],对应列indices[4:6] = [0, 3]
3. 代码示例
python
import numpy as np
from scipy.sparse import csr_matrix
# 创建稀疏矩阵
dense_matrix = np.array([[1, 0, 0, 2],
[0, 3, 4, 0],
[5, 0, 0, 6]])
# 转换为CSR格式
sparse_csr = csr_matrix(dense_matrix)
# 查看三个数组
print(f"data: {sparse_csr.data}")
print(f"indices: {sparse_csr.indices}")
print(f"indptr: {sparse_csr.indptr}")
# 从CSR格式重建
reconstructed = sparse_csr.toarray()
print(f"重建矩阵:\n{reconstructed}")
4. 优点和缺点
优点
节省内存,只存储非零元素
行切片和矩阵乘法效率高
适合行访问频繁的场景
缺点
列访问效率低
频繁插入/删除非零元素代价高
比 COO 格式复杂
5. 适用场景
机器学习中的特征矩阵(通常是行表示样本,列表示特征)
图算法中的邻接矩阵
有限元分析
任何行访问频繁的稀疏矩阵运算
CSR 格式是现代科学计算和机器学习中最常用的稀疏矩阵存储格式之一,特别是在处理大规模数据时。