我对scipy构建块对角矩阵的方式有疑问。我期望创建一个稀疏块对角矩阵比创建一个密集矩阵(由于稀疏压缩)更快更有效。但事实证明情况并非如此(或者我使用了一些效率低下的方法):
from timeit import default_timer as timer
import numpy as np
from scipy.sparse import block_diag as bd_sp
from scipy.linalg import block_diag as bd_la
m = [np.identity(1)] * 10000
before = timer()
res = bd_sp(m)
timer()-before
#takes 33.79 secs
before = timer()
res = bd_la(*m)
timer()-before
#takes 0.069 secs
我错过了什么?提前感谢您的回复。
答案 0 :(得分:0)
In [625]: [np.identity(1)*i for i in range(1,5)]
Out[625]: [array([[1.]]), array([[2.]]), array([[3.]]), array([[4.]])]
In [626]: sparse.block_diag(_)
Out[626]:
<4x4 sparse matrix of type '<class 'numpy.float64'>'
with 4 stored elements in COOrdinate format>
In [627]: _.A
Out[627]:
array([[1., 0., 0., 0.],
[0., 2., 0., 0.],
[0., 0., 3., 0.],
[0., 0., 0., 4.]])
block_diag
使用bmat
加入元素。 bmat
从所有元素生成coo
个矩阵,并将其属性与偏移量组合在一起,并生成一个新的coo
矩阵。代码是可读的Python。
构建自己的data, row, col
数组可能更有效。 block_diag
是一种方便,适用于组合几个大型矩阵,但在组合许多小型矩阵时效率不高。
linalg
函数也是Python(非常简短)。如果创建一个正确形状的out
数组,并插入带有切片索引的块。这是一种高效的密集阵列解决方案。大多数艰苦工作都是在编译的numpy
代码中完成的。
在进行矩阵乘法(和相关的linalg求解器)时,稀疏矩阵可以更快。对于大多数其他操作,包括初始化,它们比等效密集代码慢。当问题太大时,它们也很有价值。