python实现稀疏矩阵⽰例代码
⼯程实践中,多数情况下,⼤矩阵⼀般都为稀疏矩阵,所以如何处理稀疏矩阵在实际中就⾮常重要。本⽂以Python⾥中的实现为例,⾸先来探讨⼀下稀疏矩阵是如何存储表⽰的。
1.sparse模块初探
python中scipy模块中,有⼀个模块叫sparse模块,就是专门为了解决稀疏矩阵⽽⽣。本⽂的⼤部分内容,其实就是基于sparse模块⽽来的。
第⼀步⾃然就是导⼊sparse模块
>>> from scipy import sparse
然后help⼀把,先来看个⼤概
>>> help(sparse)
直接到我们最关⼼的部分:
Usage information
=================
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
python新手代码示例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
To construct a matrix efficiently, use either dok_matrix or lil_matrix.
The lil_matrix class supports basic slicing and fancy
indexing with a similar syntax to NumPy arrays. As illustrated below,
the COO format may also be used to efficiently construct matrices.
To perform manipulations such as multiplication or inversion, first
convert the matrix to either CSC or CSR format. The lil_matrix format is
row-based, so conversion to CSR is efficient, whereas conversion to CSC
is less so.
All conversions among the CSR, CSC, and COO formats are efficient,
linear-time operations.
通过这段描述,我们对sparse模块就有了个⼤致的了解。sparse模块⾥⾯有7种存储稀疏矩阵的⽅式。接下来,我们对这7种⽅式来做个⼀⼀介绍。
<_matrix
coo_matrix是最简单的存储⽅式。采⽤三个数组row、col和data保存⾮零元素的信息。这三个数组的长度相同,row保存元素的⾏,col保存元素的列,data保存元素的值。⼀般来说,coo_matrix主要⽤来创建矩阵,因为coo_matrix⽆法对矩阵的元素进⾏增删改等操作,⼀旦矩阵创建成功以后,会转化为其他形式的矩阵。
>>> row = [2,2,3,2]
>>> col = [3,4,2,3]
>>> c = _matrix((data,(row,col)),shape=(5,6))
>>> array()
[[0 0 0 0 0 0]
[0 0 0 0 0 0]
[0 0 0 5 2 0]
[0 0 3 0 0 0]
[0 0 0 0 0 0]]
稍微需要注意的⼀点是,⽤coo_matrix创建矩阵的时候,相同的⾏列坐标可以出现多次。矩阵被真正创建完成以后,相应的坐标值会加起来得到最终的结果。
3.dok_matrix与lil_matrix
dok_matrix和lil_matrix适⽤的场景是逐渐添加矩阵的元素。doc_matrix的策略是采⽤字典来记录矩阵中不为0的元素。⾃然,
字典的key存的是记录元素的位置信息的元祖,value是记录元素的具体值。
>>> import numpy as np
>>> from scipy.sparse import dok_matrix
>>> S = dok_matrix((5, 5), dtype=np.float32)
>>> for i in range(5):
...  for j in range(5):
...      S[i, j] = i + j
...
>>> array()
[[ 0. 1. 2. 3. 4.]
[ 1. 2. 3. 4. 5.]
[ 2. 3. 4. 5. 6.]
[ 3. 4. 5. 6. 7.]
[ 4. 5. 6. 7. 8.]]
lil_matrix则是使⽤两个列表存储⾮0元素。data保存每⾏中的⾮零元素,rows保存⾮零元素所在的列。这种格式也很适合逐个添加元素,并且能快速获取⾏相关的数据。
>>> from scipy.sparse import lil_matrix
>>> l = lil_matrix((6,5))
>>> l[2,3] = 1
>>> l[3,4] = 2
>>> l[3,2] = 3
>>> array()
[[ 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0.]
[ 0. 0. 0. 1. 0.]
[ 0. 0. 3. 0. 2.]
[ 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0.]]
>>> print l.data
[[] [] [1.0] [3.0, 2.0] [] []]
>>> ws
[[] [] [3] [2, 4] [] []]
由上⾯的分析很容易可以看出,上⾯两种构建稀疏矩阵的⽅式,⼀般也是⽤来通过逐渐添加⾮零元素的⽅式来构建矩阵,然后转换成其他可以快速计算的矩阵存储⽅式。
4.dia_matrix
这是⼀种对⾓线的存储⽅式。其中,列代表对⾓线,⾏代表⾏。如果对⾓线上的元素全为0,则省略。
如果原始矩阵是个对⾓性很好的矩阵那压缩率会⾮常⾼。
了⽹络上的⼀张图,⼤家就很容易能看明⽩其中的原理。
5.csr_matrix与csc_matrix
csr_matrix,全名为Compressed Sparse Row,是按⾏对矩阵进⾏压缩的。CSR需要三类数据:数值,列号,以及⾏偏移量。CSR是⼀种编码的⽅式,其中,数值与列号的含义,与coo⾥是⼀致的。⾏偏移表⽰某⼀⾏的第⼀个元素在values⾥⾯的起始偏移位置。
同样在⽹络上了⼀张图,能⽐较好反映其中的原理。
看看在python⾥怎么使⽤:
>>> 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]])
怎么样,是不是也不是很难理解。
我们再看看⽂档中是怎么说的
Notes
| -----
|
| Sparse matrices can be used in arithmetic operations: they support
| addition, subtraction, multiplication, division, and matrix power.
|
| Advantages of the CSR format
|  - efficient arithmetic operations CSR + CSR, CSR * CSR, etc.
|  - efficient row slicing
|  - fast matrix vector products
|
| Disadvantages of the CSR format
|  - slow column slicing operations (consider CSC)
|  - changes to the sparsity structure are expensive (consider LIL or DOK)
不难看出,csr_matrix⽐较适合⽤来做真正的矩阵运算。
⾄于csc_matrix,跟csr_matrix类似,只不过是基于列的⽅式压缩的,不再单独介绍。
6.bsr_matrix
Block Sparse Row format,顾名思义,是按分块的思想对矩阵进⾏压缩。
以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。