选CSR还是CSC取决于主要操作类型:行操作(如矩阵乘向量、行切片)用csr_matrix,列操作(如列切片、解方程、特征选择)用csc_matrix;构建阶段优先用coo_matrix或dok_matrix,再转为目标格式。

选对格式比盲目压缩更重要:CSR/CSC 不是万能解,COO 和 DOK 在构建阶段更灵活,但用错场景会拖慢 10 倍以上。
csr_matrix 和 csc_matrix 哪个该用?看你的主要操作类型
CSR(csr_matrix)和 CSC(csc_matrix)内存占用几乎一样,但访问模式完全不同:
- 如果你频繁做
@(矩阵乘向量)、dot、行切片(如sparse_mat[5, :]),优先用csr_matrix - 如果你常做列切片(如
sparse_mat[:, 10])、解线性方程(scipy.sparse.linalg.spsolve),或做特征选择(按列筛选特征),选csc_matrix - 误把
csc_matrix当成“通用替代”来替代 CSR,在矩阵乘法中可能慢 3–5 倍——因为底层循环遍历的是列指针,而乘法天然按行展开 - 两者互相转换(
.tocsr()/.tocsc())不是零成本,会触发完整数据重排,别在热循环里调用
构建稀疏矩阵时,别直接用 csr_matrix 或 csc_matrix
它们的构造函数接受 (data, (row, col)) 元组,但内部仍要排序+去重+压缩,效率低且不支持增量赋值:
- 用
coo_matrix构建:适合从原始三元组(比如日志里的(user_id, item_id, rating))一次性组装,支持重复索引自动累加(coo_matrix(..., dtype=np.float64)默认开启) - 用
dok_matrix构建:适合边读边写、随机赋值(如sparse_dok[123, 456] = 1.0),内部是 dict,插入快但不能直接用于计算 - 构建完立刻转成目标格式:
coo_matrix(...).tocsr()比直接csr_matrix(...)快 2–4 倍;dok_matrix转换前记得先.asformat('coo')再转,避免 dict 遍历开销
内存占用差异远大于格式名字暗示的范围
同一份非零数据,不同格式实际内存开销差异显著,尤其在小矩阵或高稀疏度下:
SkillSub Pro - Python 题解与代码注释双功能技能功能概述SkillSub Pro - Python 题解与代码注释双功能技能是一项面向实际任务的技能,主要用于SkillSub Pro 是一个 Python 题解生成与代码注释的 双功能合体技能 ,专为学生、算法学习者和开发者设计;✅ 一个技能,两种用途 :;核心要点📝 题解模式 :输入题目/题号,自动生成完整 Python 题解(含详细注释、解题思路、复杂度分析);💬 注释模式 :输入 Python 代码,自动添加详细中。它将相关步骤、
立即学习“Python免费学习笔记(深入)”;
-
coo_matrix存三个等长数组(row,col,data),总开销 ≈3 * nnz * 8字节(float64) -
csr_matrix多存一个长度为m+1的indptr,当行数m很大(比如百万级用户 ID)但nnz很小时,indptr可能吃掉几 MB 冗余内存 -
dok_matrix是 Python dict,每个键值对有哈希表开销,nnz > 10^4后就明显不如 COO - 实测:100 万 × 100 万、
nnz=5e4的矩阵,coo占 1.2 MB,csr占 1.9 MB(多出的 0.7 MB 几乎全是indptr),dok占 4.3 MB
稀疏性极高的场景,别忽略 scipy.sparse.bmat 和 block_diag
当你处理分块结构(如推荐系统中用户-物品子矩阵拼接、图神经网络中的邻接块),硬摊平成单一大矩阵会浪费空间并破坏局部性:
-
scipy.sparse.bmat支持用二维 list 构建块矩阵,不立即合并内存,延迟压缩,适合动态组合 -
scipy.sparse.block_diag对角块拼接零拷贝,比手动填充coo三元组快且安全 - 注意:这些函数输出默认是
coo_matrix,后续必须显式转成csr或csc才能高效运算,否则.dot()会先隐式转换,不可控
真正卡住性能的往往不是“用了稀疏矩阵”,而是格式切换时机不对、构建路径绕远、或者误以为 CSR 就是终极答案。矩阵维度、操作频次、构建方式这三点没对齐,再好的格式也白搭。

















