首页 > 其他分享 >【SciPy】Sparse稀疏矩阵主要存储格式总结(转载)

【SciPy】Sparse稀疏矩阵主要存储格式总结(转载)

时间:2023-04-03 23:55:46浏览次数:55  
标签:存储 mat 矩阵 SciPy Sparse data coo matrix

原文:【SciPy】Sparse稀疏矩阵主要存储格式总结

在数据科学和深度学习等领域常会采用矩阵格式来存储数据,但当矩阵较为庞大且非零元素较少时,运算效率和存储有效率并不高。所以,通常我们采用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)的形式来存储矩阵中非零元素的信息
  • 三个数组 rowcoldata 分别保存非零元素的行下标、列下标与值(一般长度相同)
  • 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

相关文章

  • 1594. 矩阵的最大非负积
    题目描述给了一个矩阵grid,里面的数字有正有负问从左上角到右下角的最大乘积?f1-dp基本分析这里有正又负会有啥问题?可能最小的负*负数会产生最大的正数,所以需要维护两个值,最大的路径积和最小的路径积怎么进行转移?只能从左边或者上面转移来,需要对grid[i][j]的值按照正负分类讨......
  • 力扣---剑指 Offer 12. 矩阵中的路径
    给定一个 mxn二维字符网格 board和一个字符串单词 word。如果 word存在于网格中,返回true;否则,返回false。单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。 例如,......
  • acwing 4405.统计子矩阵的和
    原题链接解题思路通过i和j来控制子矩阵的左右边界,通过s和t来控制子矩阵的上下边界,在子矩阵的和小于k时候,统计子矩阵的个数。代码#include<iostream>usingnamespacestd;constintN=550;inta[N][N];//i与j控制左右边界,st控制上下边界计算二维矩阵和intmai......
  • HJ70_矩阵乘法计算量估算_入门栈使用的典型题
    反思:这题咋一看不难,但是越做坑越多,按照一开始不完善的思路无法完全通过测试。参看高赞答案,代码行数特少。但是没考虑一个括号中有三个矩阵的情况。思路:1、判断哪两个矩阵开始相乘的条件:遇到“)”时,该字符前两个矩阵开始相乘。把相乘后矩阵行列数组压入栈栈中。该题默认不存在(A(......
  • HJ69_矩阵乘法_数组
    思路:三层循环实现矩阵相乘。importsysa=[]forlineinsys.stdin:  a.append(list(map(int,line.strip().split())))#print(a)matrix1=a[3:3+a[0][0]]matrix2=a[3+a[0][0]:]nw=[[0foriinrange(a[2][0])]foriinrange(a[0][0])]forminrange(a[0][0]): ......
  • 华为OD机试 和最大子矩阵
    本期题目:和最大子矩阵题目给定一个二维整数矩阵要在这个矩阵中选出一个子矩阵使得这个子矩阵内所有的数字和尽量大我们把这个子矩阵成为“和最大子矩阵”子矩阵的选取原则,是原矩阵中一段相互连续的矩形区域输入输入的第一行包含两个整数N,M (1<=N,M<=10) 表示一个......
  • 华为OD机试 和最大子矩阵
    本期题目:和最大子矩阵题目给定一个二维整数矩阵,要在这个矩阵中选出一个子矩阵,使得这个子矩阵内所有的数字和尽量大我们把这个子矩阵成为“和最大子矩阵”,子矩阵的选取原则,是原矩阵中一段相互连续的矩形区域。输入输入的第一行包含两个整数N,M (1<=N,M<=10) 表示一个N......
  • 坐标系旋转矩阵以及坐标系不变旋转点的旋转矩阵
    1.坐标系不动的情况下,绕原点旋转2.旋转坐标系的情况2.1推导情况......
  • min 与 + 运算转换成类似于矩阵乘法的推导过程
    记录下由$\min$与$+$运算转换成类似于矩阵乘法的推导过程,有错误请在评论区指出qwq。我们先简单证明一下矩阵乘法的结合律。设有矩阵$A_{n\timesm}$,$B_{m......
  • P1005 [NOIP2007 提高组] 矩阵取数游戏
    思维题:显然每个行可以互相独立来处理。贪心和暴力显然都不容易处理这题,所以我们只能考虑dp。每次只能取最左边和最右边的数,这显然很符合区间dp的特点。所以我们令dp[i]......