稀疏矩阵 (scipy.sparse
)#
SciPy 用于数值数据的二维稀疏数组包。
备注
此包正在从旧的矩阵接口切换到与 NumPy 数组兼容的数组接口。我们建议您在所有新工作中使用数组对象(bsr_array
、coo_array
等)。
在使用数组接口时,请注意以下几点:
x * y
不再执行矩阵乘法,而是执行元素逐个相乘(就像使用 NumPy 数组一样)。为了使代码同时适用于数组和矩阵,请使用x @ y
进行矩阵乘法。像 sum 这样的操作,过去生成密集矩阵,现在生成数组,其乘法行为也有类似的差异。
稀疏数组目前必须是二维的。这也意味着对这些对象的所有 切片 操作必须产生二维结果,否则将导致错误。这将在未来的版本中得到解决。
构造工具(eye
, kron
, random
, diags
等)尚未移植,但它们的结果可以包装成数组:
A = csr_array(eye(3))
内容#
稀疏数组类#
|
块稀疏行格式稀疏数组。 |
|
COOrdinate 格式的稀疏数组。 |
|
压缩稀疏列数组。 |
|
压缩稀疏行数组。 |
|
带有对角存储的稀疏数组。 |
|
基于键值字典的稀疏数组。 |
|
基于行的列表的稀疏数组。 |
|
此类为所有稀疏数组提供了一个基类。 |
稀疏矩阵类#
|
块稀疏行格式稀疏矩阵。 |
|
COOrdinate 格式的稀疏矩阵。 |
|
压缩稀疏列矩阵。 |
|
压缩稀疏行矩阵。 |
|
带有对角存储的稀疏矩阵。 |
|
基于键值字典的稀疏矩阵。 |
|
基于行的列表的稀疏矩阵。 |
|
此类为所有稀疏矩阵类提供了一个基类。 |
函数#
构建稀疏数组:
|
从对角线构建稀疏数组。 |
|
稀疏数组格式的单位矩阵 |
|
返回一个均匀分布的随机数的稀疏数组,范围在 [0, 1) 之间 |
|
从稀疏子块构建稀疏数组 |
构建稀疏矩阵:
|
对角线上为1的稀疏矩阵 |
|
稀疏格式的单位矩阵 |
|
从对角线构造一个稀疏矩阵。 |
|
从对角线返回一个稀疏矩阵。 |
|
从稀疏子块构建稀疏数组或矩阵 |
|
生成具有给定形状和密度的稀疏矩阵,其值随机分布。 |
|
生成具有给定形状和密度的稀疏矩阵,其值均匀分布。 |
从较小的(数组或矩阵)构建更大的结构
|
稀疏矩阵 A 和 B 的克罗内克积 |
|
方阵稀疏矩阵 A 和 B 的克罗内克和 |
|
从提供的矩阵构建一个块对角稀疏矩阵或数组。 |
|
返回稀疏数组或矩阵的下三角部分 |
|
返回稀疏数组或矩阵的上三角部分 |
|
水平堆叠稀疏矩阵(按列) |
|
垂直堆叠稀疏数组(按行) |
保存和加载稀疏矩阵:
|
使用 |
|
使用 |
稀疏工具:
|
返回矩阵中非零元素的索引和值 |
识别稀疏数组:
使用 isinstance(A, sp.sparse.sparray) 来检查一个数组或矩阵。
使用 A.format == ‘csr’ 来检查稀疏格式
识别稀疏矩阵:
|
x 是稀疏数组或稀疏矩阵类型吗? |
|
x 是稀疏矩阵类型吗? |
x 是 csc_matrix 类型吗? |
|
x 是 csr_matrix 类型吗? |
|
x 是 bsr_matrix 类型吗? |
|
x 是 lil_matrix 类型吗? |
|
x 是 dok_array 类型吗? |
|
x 是 coo_matrix 类型吗? |
|
x 是 dia_matrix 类型吗? |
子模块#
异常#
使用信息#
有七种可用的稀疏数组类型:
要高效地构建数组,可以使用 dok_array
或 lil_array
。lil_array
类支持基本的切片和花式索引,语法与 NumPy 数组类似。如下所示,COO 格式也可以用于高效地构建数组。尽管它们与 NumPy 数组相似,但**强烈建议不要**直接在这些数组上使用 NumPy 函数,因为 NumPy 可能无法正确转换它们以进行计算,从而导致意外(且错误)的结果。如果你确实想将 NumPy 函数应用于这些数组,首先检查 SciPy 是否为给定的稀疏数组类提供了自己的实现,或者**先将稀疏数组转换为 NumPy 数组**(例如,使用类的 toarray
方法),然后再应用该方法。
要执行乘法或求逆等操作,首先将数组转换为 CSC 或 CSR 格式。lil_array
格式是基于行的,因此转换为 CSR 是高效的,而转换为 CSC 则效率较低。
CSR、CSC 和 COO 格式之间的所有转换都是高效的、线性时间操作。
矩阵向量积#
要在稀疏数组和向量之间进行向量积,只需使用数组 dot
方法,如其在文档字符串中所述:
>>> import numpy as np
>>> from scipy.sparse import csr_array
>>> A = csr_array([[1, 2, 0], [0, 0, 3], [4, 0, 5]])
>>> v = np.array([1, 0, -1])
>>> A.dot(v)
array([ 1, -3, -1], dtype=int64)
警告
截至 NumPy 1.7 版本,np.dot
不支持稀疏数组,因此使用它会导致意外的结果或错误。应首先获取相应的密集数组:
>>> np.dot(A.toarray(), v)
array([ 1, -3, -1], dtype=int64)
但这样一来,所有的性能优势都将丧失。
CSR 格式特别适合快速矩阵向量乘积。
示例 1#
构建一个 1000x1000 的 lil_array
并向其中添加一些值:
>>> from scipy.sparse import lil_array
>>> from scipy.sparse.linalg import spsolve
>>> from numpy.linalg import solve, norm
>>> from numpy.random import rand
>>> A = lil_array((1000, 1000))
>>> A[0, :100] = rand(100)
>>> A.setdiag(rand(1000))
现在将其转换为CSR格式并求解 A x = b 中的 x:
>>> A = A.tocsr()
>>> b = rand(1000)
>>> x = spsolve(A, b)
将其转换为密集数组并求解,并检查结果是否相同:
>>> x_ = solve(A.toarray(), b)
现在我们可以用以下方法计算误差的范数:
>>> err = norm(x-x_)
>>> err < 1e-10
True
它应该很小 :)
示例 2#
以COO格式构建一个数组:
>>> from scipy import sparse
>>> from numpy import array
>>> I = array([0,3,1,0])
>>> J = array([0,3,1,2])
>>> V = array([4,5,7,9])
>>> A = sparse.coo_array((V,(I,J)),shape=(4,4))
请注意,索引不需要排序。
在转换为CSR或CSC格式时,重复的 (i,j) 条目会被求和。
>>> I = array([0,0,1,3,1,0,0])
>>> J = array([0,2,1,3,1,0,0])
>>> V = array([1,1,1,1,1,1,1])
>>> B = sparse.coo_array((V,(I,J)),shape=(4,4)).tocsr()
这对于构建有限元刚度和质量矩阵非常有用。
更多细节#
CSR 列索引不一定是有序的。同样地,CSC 行索引也是如此。当需要有序索引时(例如,在将数据传递给其他库时),请使用 .sorted_indices()
和 .sort_indices()
方法。