sparsearray存储超大规模稀疏矩阵应优先选用csr或csc格式,避免coo;需批量初始化而非逐个赋值,警惕隐式零导致的稠密化,合理选用dtype并定期清理零值。

用 SparseArray 存储含大量零值的超大规模矩阵,核心是只存非零元素及其位置,跳过所有零,大幅节省内存并加速运算。关键不在“怎么建”,而在“选对格式”和“避开常见坑”。
优先选 CSR 或 CSC 格式,别用 COO 做大规模计算
COO(坐标格式)最直观:三个数组分别存行索引、列索引、值,适合构建和小批量插入。但一做矩阵乘法或求解就慢,且不支持原地修改。超大规模场景下,应转为 CSR(按行压缩)或 CSC(按列压缩):
- CSR 适合按行访问、行向量乘法、大多数迭代求解器(如 CG);
- CSC 更适合作列切片、特征提取、与 sklearn 的 fit/transform 流程天然兼容;
- SciPy 中 sparse.csr_matrix() 和 sparse.csc_matrix() 构造后即优化存储,索引查找快、算术操作高度向量化。
构建时避免逐个赋值,用批量数据一次性初始化
写 mat[i, j] = x 看似自然,实则每次触发结构检查和内存重分配,100 万次赋值可能卡死。正确做法是先收集全部非零项,再统一构造:
- 用 Python 列表暂存 (row, col, value) 元组,最后传给 sparse.coo_matrix((data, (rows, cols)), shape=(M,N));
- 若已知每行/列非零元数量,可预分配 CSR/CSC 的 indptr 数组,进一步减少内存拷贝;
- 从 HDF5 或 Parquet 读稀疏数据时,优先用 sparse.load_npz() 加载已压缩的 .npz 文件,比现场解析快 5–10 倍。
注意隐式零与显式零的区别,避免意外 densify
SparseArray 不存零,但 mat[0, 0] 返回 0 是“逻辑零”,不是“存储了零”。问题常出在:
- 调用 mat.toarray() 或 np.array(mat) 会强制展开成稠密数组,10⁶×10⁶ 矩阵瞬间 OOM;
- 和标量做运算如 mat + 1,结果仍是稀疏的,但 mat == 0 会返回稠密布尔矩阵——务必改用 mat.count_nonzero() 或 mat.sum() 替代;
- 用 np.where(mat) 提取非零位置前,确认 mat 是 CSR/CSC,否则 COO 下效率极低。
配合 dtype 和压缩策略进一步减负
默认 float64 占 8 字节,但很多场景 float32 或 int32 已足够:
- 创建时显式指定 dtype=np.float32,内存直降 50%,多数科学计算精度无损;
- 计数类矩阵(如 TF-IDF、共现表)用 dtype=np.int32 更省;
- 加载后调用 mat.eliminate_zeros() 清理重复索引和浮点误差引入的“近零值”;
- 长期保存用 sparse.save_npz("mat.npz", mat),比 pickle 小 3–5 倍,且跨平台可读。










