# 稀疏矩阵的类型

**scipy.sparse**中提供了多种格式的稀疏矩阵, 每种都有自己的特点, 根据实际情况与需要选择使用. 因此要充分了解各种稀疏矩阵的特点.

```python
from scipy.sparse import csr_matrix, csc_matrix, coo_matrix, dia_matrix, dok_matrix, lil_matrix
```

## CSR Matrix

**Compressed Sparse Row matrix**.

### 初始化方法

* **csr\_matrix(D)**
  * D表示dense matrix
* **csr\_matrix(S)**
  * S表示其他的稀疏矩阵, 相当于`S.tocsr()`
* **csr\_matrix((M, N), \[dtype])**
  * 创建一个shape为(M, N)的空的稀疏矩阵
* **csr\_matrix((data, (row\_ind, col\_ind)), \[shape=(M, N)])**
  * `data`, `row_ind`, `col_ind`对应着`a[row_ind[k], col_ind[k]] = data[k]`
  * 如果不指定`shape`, 则从传入的参数中自动推断
* **csr\_matrix((data, indices, indptr), \[shape=(M, N)])**
  * 这种形式就是**CSR**的标准形式
  * 第`i`行的有值的列索引存储在`indices[indptr[i]:indptr[i+1]]`
  * 对应的值存储在`data[indptr[i]:indptr[i+1]]`
  * indptr相当于存储着每一行起始终止位置. 因此CSR这种形式是把所有的行数据存储在一个扁平列表中, 因此需要记录分隔位置.

```python
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]])
```

### 优点

* 数学计算效率高, 加乘等
* 行切片效率高
* 向量, 矩阵乘法效率高

### 缺点

* 列切片慢
* 转换成其他格式的稀疏矩阵慢(如LIL, DOK)

## CSC Matrix

**Compressed Sparse Column matrix**.

### 初始化方法

* **csc\_matrix(D)**
  * D表示dense matrix
* **csc\_matrix(S)**
  * S表示其他的稀疏矩阵, 相当于`S.tocsc()`
* **csc\_matrix((M, N), \[dtype])**
  * 创建一个shape为(M, N)的空的稀疏矩阵
* **csc\_matrix((data, (row\_ind, col\_ind)), \[shape=(M, N)])**
  * `data`, `row_ind`, `col_ind`对应着`a[row_ind[k], col_ind[k]] = data[k]`
  * 如果不指定`shape`, 则从传入的参数中自动推断
* **csc\_matrix((data, indices, indptr), \[shape=(M, N)])**
  * 这种形式就是**CSR**的标准形式
  * 第`i`列的有值的行索引存储在`indices[indptr[i]:indptr[i+1]]`
  * 对应的值存储在`data[indptr[i]:indptr[i+1]]`
  * indptr相当于存储着每一列起始终止位置. 因此CSR这种形式是把所有的列数据存储在一个扁平列表中, 因此需要记录分隔位置.

```python
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, 4],
       [0, 0, 5],
       [2, 3, 6]])
```

### 优点

* 数学计算效率高, 加乘等
* 列切片效率高
* 向量, 矩阵乘法效率高

### 缺点

* 行切片慢
* 转换成其他格式的稀疏矩阵慢(如LIL, DOK)

## COO Matrix

**A sparse matrix in COOrdinate format**.

### 初始化方法

* **coo\_matrix(D)**
  * D表示dense matrix
* **coo\_matrix(S)**
  * S表示其他的稀疏矩阵, 相当于`S.tocoo()`
* **coo\_matrix((data, (row\_ind, col\_ind)), \[shape=(M, N)])**
  * `data`, `row_ind`, `col_ind`对应着`a[row_ind[k], col_ind[k]] = data[k]`

```python
>>> # Constructing a matrix using ijv format
>>> row  = np.array([0, 3, 1, 0])
>>> col  = np.array([0, 3, 1, 2])
>>> data = np.array([4, 5, 7, 9])
>>> 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]])
```

```python
>>> # Constructing a matrix with duplicate indices
>>> row  = np.array([0, 0, 1, 3, 1, 0, 0])
>>> col  = np.array([0, 2, 1, 3, 1, 0, 0])
>>> data = np.array([1, 1, 1, 1, 1, 1, 1])
>>> coo = coo_matrix((data, (row, col)), shape=(4, 4))
>>> # Duplicate indices are maintained until implicitly or explicitly summed
>>> np.max(coo.data)
1
>>> coo.toarray()
array([[3, 0, 1, 0],
       [0, 2, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 1]])
```

### 优点

* 与各种形式的稀疏矩阵之间的转换高效, 特别是与`csr/csc`之间相互的转换
* 输入时允许有重复位置的输入

### 缺点

* 不支持切片
* 不支持数学运算

### 应用场景

* COO是一种快速创建稀疏矩阵的格式, 新建稀疏矩阵很高效
* 一般是使用COO创建稀疏矩阵, 然后转为CSR或CSC格式进行矩阵的计算
* 转换成CSR或CSC格式时, 重复位置的元素会被加和

## LIL Matrix

**Row-based linked list sparse matrix**

### 数据格式

每行为一个array, 这个array的内容为排序好的非0位置的索引, 对应的data的array要与索引保持相同的格式且对齐.

### 应用场景

这是用来增量添加来创建稀疏矩阵的格式. 注意在向已有的矩阵添加元素时, 要先排序, 然后再顺序添加.

这里的添加指的是使用切片指定添加.

### 初始化方法

* **lil\_matrix(D)**
  * D表示dense matrix
* **lil\_matrix(S)**
  * S表示其他的稀疏矩阵, 相当于`S.tocoo()`
* **lil\_matrix((M, N), \[dtype])**
  * 创建一个shape为(M, N)的空的稀疏矩阵

### 优点

* 支持灵活的切片
* 转换成其他稀疏矩阵很高效

### 缺点

* 两个LIL类型的稀疏矩阵之间的加法很慢, 要先转换成`CSR/CSC`格式
* 列切片很慢
* 矩阵乘积很慢

## DOK Matrix

**Dictionary Of Keys based sparse matrix**.

### 应用场景

这也是一种创建后增量增补数据的高效格式, 与LIL的区别在于保存数据的形式, LIL的是列表形式, DOK是字典的形式.

### 初始化方法

* **dok\_matrix(D)**
  * D表示dense matrix
* **dok\_matrix(S)**
  * S表示其他的稀疏矩阵, 相当于`S.tocoo()`
* **dok\_matrix((M, N), \[dtype])**
  * 创建一个shape为(M, N)的空的稀疏矩阵

### 优点

* 由于是使用字典格式保存每个位置的值, 因此对单个值的查询和赋值都是在`O(1)`内完成的, 非常高效.

## DIA Matrix

**Sparse matrix with DIAgonal storage**.

### 初始化方法

* **dia\_matrix(D)**
  * D表示dense matrix
* **dia\_matrix(S)**
  * S表示其他的稀疏矩阵, 相当于`S.tocoo()`
* **dia\_matrix((M, N), \[dtype])**
  * 创建一个shape为(M, N)的空的稀疏矩阵
* **dia\_matrix((data, offsets), shape=(M, N))**
  * 见例子[Diagonal Format (DIA)](http://scipy-lectures.org/advanced/scipy_sparse/dia_matrix.html)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://kerasnoone.gitbook.io/garnet/gong-cheng-zhan/python/scipy/xi-shu-ju-zhen/xi-shu-ju-zhen-de-lei-xing.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
