scipy.sparse.coo_matrix、csr_matrix、lil_matrix、dia_matrix

coo_matrix

1.coo啥意思?COOrdinate(坐标)

2.那么coo_matrix又是一个啥?这么跟你说吧,稀疏矩阵有很多表示的方法,其中coo_matrix是一种,其表示稀疏矩阵所用的方法名字就叫做COOrdinate或者叫做ijv,triplet

A sparse matrix in COOrdinate format.

Also known as the ‘ijv’ or ‘triplet’ format.

首先,我们要明白,矩阵可以看作是一个坐标,每一个坐标上都有一个值。

怕你英语不好

  1. ijv:(i,j,value),其中i,j都行索引,列索引,value是坐标(i,j)上的值。
  2. triplet:三元组,也是一个意思。

3.coo_matrix的构造方法:
直接构造法

from scipy.sparse import coo_matrix
row  = np.array([0, 3, 1, 0])#i
col  = np.array([0, 3, 1, 2])#j
data = np.array([4, 5, 7, 9])#v
coo_matrix((data, (row, col)), shape=(4, 4)).toarray()

结果如下:

array([[4, 0, 9, 0],
[0, 7, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 5]])

可以看到,矩阵(0,0)上的值4,正好对应于ijv格式,或者叫做坐标格式。
间接构造法

from scipy.sparse import coo_matrix
a=np.identity(3)#n=3的单位矩阵
coo_matrix(a).toarray()

array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])

我们上面是先构造一个其他类型的矩阵,然后把他转化成coo_matrix.

csr_matrix

Compressed Sparse Row matrix

矩阵有行有列,为什么偏偏这里要说行row?这也和其表示有关,其思想是:你需要告诉我每一行都有哪些列有值(即非零),以及值是什么。
所以有了如下:

data = np.array([1, 2, 3, 4, 5, 6])
indices = np.array([0, 2, 2, 0, 1, 2])

data就是值了,indices指的就是这些值对应的是哪一列,不过不对啊,没有说对应哪一行?所以我们还有一个参数:

indptr = np.array([0, 2, 3, 6])

上面这个参数,告诉我们indices中哪些列是属于第一行的,哪些列是属于第二行的,。。。。我们来看看indptr,其有4个数,表示一共有3行,因为可以划分成[0,2),[2, 3),[3, 6),这表示indices中[0,2)(即前两个数)属于第0行,其他依次类推。我们发现indices中的6个数刚好分配到3行中去。

明白了原理之后,我们可以构造csr_matrix,方法如下:
标准构造

import numpy as np
from scipy.sparse import csr_matrix
indptr = np.array([0, 2, 3, 6])
indices = np.array([0, 2, 2, 0, 1, 2])
data = np.array([1, 2, 3, 4, 5, 6])
csr_matrix((data, indices, indptr), shape=(3, 3)).toarray()

array([[1, 0, 2],
[0, 0, 3],
[4, 5, 6]])

其他构造
我们可以使用前一小节介绍的两种方法构造也行,只需将coo_matrix改成csr_matrix。

lil_matrix

Row-based list of lists sparse matrix

This is a structure for constructing sparse matrices incrementally. Note that inserting a single item can take linear time in the worst case; to construct a matrix efficiently, make sure the items are pre-sorted by index, per row.

那么其到底是怎么实现的呢?
在这里插入图片描述
说白了,由于我们是稀疏矩阵,也就是说0多非0少,所以总原则仍然是只存储非0元素。

上面的图片不知道你看懂了没有,我们可以举一个例子:

import numpy as np
from scipy.sparse import lil_matrix
a=np.random.randint(0,2,(2,3))
print(a)

在这里插入图片描述

spa = lil_matrix(a)
print(spa)

在这里插入图片描述
有人会说,这个怎么这么像第一种坐标表示形式。一点区别都没有啊。其实,只是这里打印print会这样显示而已。内部其实不是这样的,而是:

索引:[[0],[1]]每一行都是一个列表,第一行就是[0],第二行就是[1]。这代表(1,1}有值,如果是[[0],[1,2]],就代表(1,1),(1,2)都有值
值:[[1],[1]]和上面一一对应的值。

而且值得一提的是,每一行里面的值是顺序增大的,也就是说:(0,0),(0,1)有值,里面会写成[[0,1]],而不是[[1,0]]。

所以说,你可以看到,这种稀疏存储结构,如果你在一行的后面插入新的元素,这个形式很方便。只需要索引列表中append一下,值列表中append一下就可以。但是往一行的中间插入就不好了,需要查找然后定位插入位置。

另外,其优点是切片很方便,比如你要第一行的,这个超级快,只需要去索引中第一行和值中的第一行。取第一列也很快,把每一行的第一个数看一下是不是1就行,是就取出来。

即:

1.efficient for constructing sparse matrices incrementally
2.flexible slicing

dia_matrix

from scipy.sparse import dia_matrix

Sparse matrix with DIAgonal storage

也就是说其存储的方式是按照对角线来存储,比如如果其是一个三对角矩阵,那么其只需要存储3行,[-1,0,1],但是这3行中如果有0,也必须存储。
比如下面的5*5的全0矩阵,假设其是3对角矩阵,即只有3个对角线上有非零值,其他为0,那么按照对角存储的时候,我们应该提供:

在这里插入图片描述
应该提供:

a=np.array([[1,2,3,0,2],[2,0,2,3,4],[1,0,0,3,4]])
offsets=np.array([0,1,-1])#表示上面的第一行是0对角线上的值。
#第二行是1对角线上的值。

那么就有一个问题了,5*5的矩阵,主对角线上(0对角线)确实有5个元素,那为什么1对角线(上面那个对角)也有5个元素呢?不应该是4个吗?

答案:确实是4个,有一个其实是多余的。那个多余的值你可以随便填什么,都不会有影响。

dia_matrix((a, offsets), shape=(5, 5)).toarray()

在这里插入图片描述
可以看到对于1对角线,我们提供第一个元素是多余的,-1对角线最后一个元素是多余的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

音程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值