在数据科学和深度学习等领域常会采用矩阵格式来存储数据,但当矩阵较为庞大且非零元素较少时,运算效率和存储有效率并不高。所以,通常我们采用Sparse稀疏矩阵的方式来存储矩阵,提高存储和运算效率。下面将对SciPy中七种常见的存储方式(COO/ CSR/ CSC/ BSR/ DOK/ LIL/ DIA)的概念和用法进行介绍和对比总结。
稀疏矩阵简介
稀疏矩阵
numpy.sparse | 稀疏矩阵 | sparse matrix |
numpy.ndarray | 密集矩阵 | array matrix |
numpy.matrix | 密集矩阵 | dense matrix |
- 稀疏矩阵
- 具有少量非零项的矩阵 - Number of Non-Zero (NNZ) < 0.5
- (在矩阵中,若数值0的元素数目远多于非0元素的数目,并且非0元素分布没有规律)
- 矩阵的稠密度
- 非零元素的总数比上矩阵所有元素的总数为矩阵的稠密度。
压缩存储
存储矩阵的一般方法是采用二维数组,其优点是可以随机地访问每一个元素,因而能够容易实现矩阵的各种运算。
对于稀疏矩阵,它通常具有很大的维度,有时甚大到整个矩阵(零元素)占用了绝大部分内存
采用二维数组的存储方法既浪费大量的存储单元来存放零元素,又要在运算中浪费大量的时间来进行零元素的无效运算。因此必须考虑对稀疏矩阵进行压缩存储(只存储非零元素)。
from scipy import sparse
help(sparse)
'''
Sparse Matrix Storage Formats
There are seven available sparse matrix types:
1. csc_matrix: Compressed Sparse Column format
2. csr_matrix: Compressed Sparse Row format
3. bsr_matrix: Block Sparse Row format
4. lil_matrix: List of Lists format
5. dok_matrix: Dictionary of Keys format
6. coo_matrix: COOrdinate format (aka IJV, triplet format)
7. dia_matrix: DIAgonal format
8. spmatrix: Sparse matrix base clas
'''
矩阵属性
from scipy.sparse import csr_matrix
### 共有属性
mat.shape # 矩阵形状
mat.dtype # 数据类型
mat.ndim # 矩阵维度
mat.nnz # 非零个数
mat.data # 非零值, 一维数组
### COO 特有的
coo.row # 矩阵行索引
coo.col # 矩阵列索引
### CSR\CSC\BSR 特有的
bsr.indices # 索引数组
bsr.indptr # 指针数组
bsr.has_sorted_indices # 索引是否排序
bsr.blocksize # BSR矩阵块大小
通用方法
import scipy.sparse as sp
### 转换矩阵格式
tobsr()、tocsr()、to_csc()、to_dia()、to_dok()、to_lil()
mat.toarray() # 转为array
mat.todense() # 转为dense
# 返回给定格式的稀疏矩阵
mat.asformat(format)
# 返回给定元素格式的稀疏矩阵
mat.astype(t)
### 检查矩阵格式
issparse、isspmatrix_lil、isspmatrix_csc、isspmatrix_csr
sp.issparse(mat)
### 获取矩阵数据
mat.getcol(j) # 返回矩阵列j的一个拷贝,作为一个(mx 1) 稀疏矩阵 (列向量)
mat.getrow(i) # 返回矩阵行i的一个拷贝,作为一个(1 x n) 稀疏矩阵 (行向量)
mat.nonzero() # 非0元索引
mat.diagonal() # 返回矩阵主对角元素
mat.max([axis]) # 给定轴的矩阵最大元素
### 矩阵运算
mat += mat # 加
mat = mat * 5 # 乘
mat.dot(other) # 坐标点积
resize(self, *shape)
transpose(self[, axes, copy])
稀疏矩阵分类
COO - coo_matrix
Coordinate Matrix 对角存储矩阵
- 采用三元组
(row, col, data)
(或称为ijv format)的形式来存储矩阵中非零元素的信息 - 三个数组
row
、col
和data
分别保存非零元素的行下标、列下标与值(一般长度相同) - 故
coo[row[k]][col[k]] = data[k]
,即矩阵的第row[k]
行、第col[k]
列的值为data[k]
- 当
row[0] = 1
,column[0] = 1
时,data[0] = 2
,故coo[1][1] = 2
- 当
row[3] = 0
,column[3] = 2
时,data[3] = 9
,故coo[0][3] = 9
适用场景
- 主要用来创建矩阵,因为coo_matrix无法对矩阵的元素进行增删改等操作
- 一旦创建之后,除了将之转换成其它格式的矩阵,几乎无法对其做任何操作和矩阵运算
优缺点
优点
- 转换成其它存储格式很快捷简便(
tobsr()
、tocsr()
、to_csc()
、to_dia()
、to_dok()
、to_lil()
) - 能与CSR / CSC格式的快速转换
- 允许重复的索引(例如在1行1列处存了值2.0,又在1行1列处存了值3.0,则转换成其它矩阵时就是2.0+3.0=5.0)
缺点
- 不支持切片和算术运算操作
- 如果稀疏矩阵仅包含非0元素的对角线,则对角存储格式(DIA)可以减少非0元素定位的信息量
- 这种存储格式对有限元素或者有限差分离散化的矩阵尤其有效
实例化方法
coo_matrix(D)
:D代表密集矩阵;coo_matrix(S)
:S代表其他类型稀疏矩阵coo_matrix((M, N), [dtype])
:构建一个shape为M*N的空矩阵,默认数据类型是d,coo_matrix((data, (i, j)), [shape=(M, N)]))
:三元组初始化i[:]
: 行索引j[:]
: 列索引A[i[k], j[k]]=data[k]
特殊属性
data
:稀疏矩阵存储的值,是一个一维数组row
:与data
同等长度的一维数组,表征data
中每个元素的行号col
:与data
同等长度的一维数组,表征data
中每个元素的列号
代码示例
# 数据
row = [0, 1, 2, 2]
col = [0, 1, 2, 3]
data = [1, 2, 3, 4]
# 生成coo格式的矩阵
# <class 'scipy.sparse.coo.coo_matrix'>
coo_mat = sparse.coo_matrix((data, (row, col)), shape=(4, 4), dtype=np.int)
# coordinate-value format
print(coo)
'''
(0, 0) 1
(1, 1) 2
(2, 2) 3
(3, 3) 4
'''
# 查看数据
coo.data
coo.row
coo.col
# 转化array
# <class 'numpy.ndarray'>
coo_mat.toarray()
'''
array([[1, 0, 0, 0],
[0, 2, 0, 0],
[0, 0, 3, 4],
[0, 0, 0, 0]])
'''
标签:存储,mat,矩阵,SciPy,Sparse,data,coo,matrix
From: https://www.cnblogs.com/coco02/p/17284939.html