安装:pip install scipy
描述:就是专门为了解决稀疏矩阵而生。导入模块:from scipy import sparse
七种矩阵类型 | 描述 |
---|---|
coo_matrix ★ |
【名称】coordinate format 【优点】 ① 不同稀疏格式间转换效率高(特别是CSR和CSC) ② 不支持元素的存取和增删,但是易于保存和读取。 ③ 构建矩阵时,允许坐标重复。 【缺点】 ① 不能直接运算; ② 不能直接切片操作。 |
dok_matrix | 【说明】基于Keys的稀疏矩阵字典. (Dictionary of Keys format) 【功能】创建、转换 |
lil_matrix ★ |
【名称】基于行的链表稀疏矩阵 (List of Lists format) 【优点】 ① 快速按行切片 ② 高效地添加、删除、查找元素 【缺点】 ① 按列切片很慢(建议CSC) ② 算术运算LIL+LIL很慢(考虑CSR或CSC) |
csr_matrix | 【名称】Compressed Sparse Row format 【优点】 ① 高效的矩阵加法与乘法内积运算 ② 高效的行切片操作 ③ CSR格式在存储稀疏矩阵时非零元素平均使用的字节数(Bytes per Nonzero Entry)最为稳定(float类型约为8.5,double类型约为12.5)CSR格式常用于读入数据后进行稀疏矩阵计算。 【缺点】 ① 列切片操作慢(相比CSC) ② 转换成稀疏结构成本高(相比LIL) |
csc_matrix | 【名称】Compressed Sparse Column format 【优点】 ① 高效的矩阵加法与乘法内积运算 ② 高效的列切片操作 【缺点】 ① 矩阵内积操作没有CSR快 ② 行切片操作慢(相比CSR) ③ 转换成稀疏结构成本高(相比LIL) |
bsr_matrix | 【名称】Block Sparse Row format |
dia_matrix | 【名称】DIAgonal format |
创建
# 方式一:ijv 创建
>>> data = [5,2,3,0]
>>> 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]]
# 方式二:创建零矩阵
>>> from scipy.sparse import coo_matrix
>>> coo_matrix((3, 4), dtype=np.int8).toarray()
array([[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]], dtype=int8)
# 方式三:创建有重复索引的矩阵
>>> 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]])
【预处理】
# 整个过程是为了创建对称矩阵
# coo.T.multiply(coo.T > coo):找出不对称的正元素,并转置
# -coo.multiply(coo.T > coo):找出不对称的负元素,并将其删掉
coo = coo + coo.T.multiply(coo.T > coo) - coo.multiply(coo.T > coo)
【保存和读取】
import scipy.sparse as sparse
sparse.save_npz("coo_matrix.npz",coo_save)
coo=sparse.load_npz("coo_matrix.npz")
【转换】
# 转化为其他格式
>>> coo.tocsc()
>>> coo.tocsr()
>>> coo.todense() # 转化为 numpy.matrix类型
【转置】
# 转置
coo.T
创建
# 创建
>>> 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
获取索引
from scipy.sparse import dok_matrix
S=dok_matrix((10,10),dtype=int)
S[1,1]=10
S[1,2]=10
S[1,3]=10
S[1,8]=10
tmp=(S[1,:]==10)
print(tmp.indices)
>>>
[1 2 3 8]
转换
# convert to coo
S.tocoo()
# convert to numpy
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.]]
【适用的场景】逐渐添加矩阵的元素。
【使用】
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.sum(0))
>>>
[[0. 0. 3. 1. 2.]]
# 行求和
print(l.sum(1))
>>>
[[0.]
[0.]
[1.]
[5.]
[0.]
[0.]]
【使用】
>>> #data定义对角线元素,在这里是[1,2,3,4]。
>>> data = np.array([[1, 2, 3, 4]]).repeat(3, axis=0)
>>> #offsets定义对角线的偏移量,0代表正对角线,正数代表往上偏移,负数代表往下偏移
>>> offsets = np.array([0, -1, 2])
>>> dia_matrix((data, offsets), shape=(4, 4)).toarray()
array([[1, 0, 3, 0],
[1, 2, 0, 4],
[0, 2, 3, 0],
[0, 0, 3, 4]])
【使用】
>>> 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]])
import numpy as np
from scipy.sparse import csr_matrix
arr = np.array([0, 0, 0, 0, 0, 1, 1, 0, 2])
# 【创建压缩稀疏行】
print(csr_matrix(arr))
(0, 5) 1
(0, 6) 1
(0, 8) 2
#【查看存储的不含0元素的数据】
print(csr_matrix(arr).data)
#【计算非0元素的总数】
print(csr_matrix(arr).count_nonzero())
#【 删除矩阵中0元素】
mat = csr_matrix(arr)
mat.eliminate_zeros()
#【删除重复项】
mat = csr_matrix(arr)
mat.sum_duplicates()
#【行压缩(csr)转为列压缩(csc)】
newarr = csr_matrix(arr).tocsc()
【说明】压缩稀疏列矩阵(Compressed sparse column matrix)
【使用】
【使用】
BSR矩阵中的inptr列表的第i个元素与i+1个元素是储存第i行的数据的列索引以及数据的区间索引,即indices[indptr[i]:indptr[i+1]]为第i行元素的列索引,data[indptr[i]: indptr[i+1]]为第i行元素的data。在下面的例子中,对于第0行,indptr[0]:indptr[1] -> 0:2, 因此第0行的列为indice[0:2]=[0,2],data为data[0:2]=array([[[1, 1],[1, 1]],[[2, 2],[2, 2]]]),对应的就是最后结果的第0,1行.
>>> 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]).repeat(4).reshape(6, 2, 2)
>>> bsr_matrix((data,indices,indptr), shape=(6, 6)).toarray()
array([[1, 1, 0, 0, 2, 2],
[1, 1, 0, 0, 2, 2],
[0, 0, 0, 0, 3, 3],
[0, 0, 0, 0, 3, 3],
[4, 4, 5, 5, 6, 6],
[4, 4, 5, 5, 6, 6]])