行业资讯
📅 2026/7/9 1:50:08
COO、CSR、CSC 稀疏矩阵完整构造原理
先用一个小矩阵举例统一演示三种格式怎么存数据。 设原稀疏矩阵 A3 行 4 列​​非零元素一共 5 个一、COO 坐标格式 Coordinate存储三个等长数组data所有非零数值row对应元素的行下标col对应元素的列下标上面例子构造data [5, 2, 3, 1, 4] row [0, 1, 1, 2, 2] col [1, 0, 2, 1, 3]含义(row [0], col [0]) (0,1) → 值 5(row [1], col [1]) (1,0) → 值 2 以此类推。特点构造最简单直接遍历矩阵把非零三元组存起来不能直接切片、矩阵乘法很慢一般只用来做格式转换中间载体允许重复坐标可相加合并。二、CSR 行压缩格式 Compressed Sparse Row三组存储数组data所有非零值按行优先顺序排列indices每个非零元素对应的列号和 data 一一对应indptr行偏移指针长度 行数 1indptr[i]第 i 行第一个非零元素在 data/indices 里的起始下标indptr[i1]第 i 行末尾下标 1第 i 行所有元素范围data[indptr[i] : indptr[i1]]用示例矩阵一步步构造按行遍历收集非零行优先 行 0只有 5列 1 行 12 (列 0), 3 (列 2) 行 21 (列 1), 4 (列 3)data、indicesdata [5, 2, 3, 1, 4] indices [1, 0, 2, 1, 3]构造 indptr3 行 → indptr 长度 4行 0 前 0 个元素 → indptr [0] 0行 0 共 1 个 → indptr [1] 01 1行 1 共 2 个 → indptr [2] 12 3行 2 共 2 个 → indptr [3] 32 5indptr [0, 1, 3, 5]读取验证取第 1 行i1起止区间indptr[1]1~indptr[2]3data [1:3] [2,3]indices [1:3] [0,2]对应原矩阵第 1 行两个元素正确。CSR 核心优势快速按行访问、行切片、矩阵向量乘法 A・x机器学习、图计算默认格式。三、CSC 列压缩格式 Compressed Sparse Column逻辑和 CSR 完全对称只是按列优先存储。 三组数组data非零值按列从上到下排序indices每个非零对应的行下标indptr列偏移指针长度 列数 1indptr[j]第 j 列第一个元素在 data 的起始位置示例矩阵构造先按列遍历非零元素 列 02 (行 1) 列 15 (行 0), 1 (行 2) 列 23 (行 1) 列 34 (行 2)data、indicesdata [2, 5, 1, 3, 4] indices [1, 0, 2, 1, 2]indptr4 列 → 长度 5列 01 个 → 0~1列 12 个 → 1~3列 21 个 → 3~4列 31 个 → 4~5indptr [0, 1, 3, 4, 5]读取验证取第 1 列 j1区间indptr[1]1~indptr[2]3data [1:3] [5,1]indices [1:3] [0,2]对应列 1 两个元素正确。CSC 核心优势快速按列访问、列切片、Aᵀ・x有限元、数值求解常用。三者构造流程对比总结COO 构造双重循环遍历矩阵只要 A [i,j]≠0就把 i,j,v 分别追加进 row/col/data无顺序要求。CSR 构造两种方式方式 1从 COO 转换先按行排序三元组再统计每行元素数量生成 indptr方式 2直接遍历矩阵逐行收集非零同步填充 data、indices、indptr。CSC 构造方式 1从 COO 转换按列排序三元组统计每列元素生成 indptr方式 2逐列遍历矩阵按列收集非零。极简记忆COO存 (行列值) 三元组最简单CSR按行打包行指针 indptr适合行操作CSC按列打包列指针 indptr适合列操作。Python 简易构造代码示例python运行import scipy.sparse as sp import numpy as np # 原矩阵 A_dense np.array([ [0,5,0,0], [2,0,3,0], [0,1,0,4] ]) # 1. COO A_coo sp.coo_matrix(A_dense) print(COO data:, A_coo.data) print(COO row:, A_coo.row) print(COO col:, A_coo.col) # 2. CSR A_csr A_coo.tocsr() print(\nCSR data:, A_csr.data) print(CSR indices:, A_csr.indices) print(CSR indptr:, A_csr.indptr) # 3. CSC A_csc A_coo.tocsc() print(\nCSC data:, A_csc.data) print(CSC indices:, A_csc.indices) print(CSC indptr:, A_csc.indptr)运行输出和上面手工推导的数组完全一致。