# scipy稀疏矩阵模块

3,137次阅读

## 1.sparse模块初探

python中scipy模块中，有一个模块叫sparse模块，就是专门为了解决稀疏矩阵而生。本文的大部分内容，其实就是基于sparse模块而来的。

>>> from scipy import sparse

>>> 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
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.

## 2.coo_matrix

coo_matrix是最简单的存储方式。采用三个数组row、col和data保存非零元素的信息。这三个数组的长度相同，row保存元素的行，col保存元素的列，data保存元素的值。一般来说，coo_matrix主要用来创建矩阵，因为coo_matrix无法对矩阵的元素进行增删改等操作，一旦矩阵创建成功以后，会转化为其他形式的矩阵。

>>> row = [2,2,3,2]
>>> col = [3,4,2,3]
>>> c = sparse.coo_matrix((data,(row,col)),shape=(5,6))
>>> print c.toarray()
[[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]]

## 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
...
>>> print S.toarray()
[[ 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
>>> print l.toarray()
[[ 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] [] []]
>>> print l.rows
[[] [] [3] [2, 4] [] []]

## 5.csr_matrix与csc_matrix

csr_matrix，全名为Compressed Sparse Row，是按行对矩阵进行压缩的。CSR需要三类数据：数值，列号，以及行偏移量。CSR是一种编码的方式，其中，数值与列号的含义，与coo里是一致的。行偏移表示某一行的第一个元素在values里面的起始偏移位置。

>>> 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)

## 6.bsr_matrix

block_size为2时，分块表示的压缩矩阵E：

BSR的zero-based索引表示：

values  =  (1 02 1 6 7 8 2 1 4 5 1 4 3 0 0 7 2 0 0)

columns  = (0  1   1   1   2)

pointerB= (0   2  3)

pointerE= (2   3  5)