我有一个关于 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
我错过了什么?提前感谢您的回复。
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(而且很短(。 If 创建正确形状的 out
数组,并插入具有切片索引的块。 这是一种高效的密集阵列解决方案。 大部分艰苦的工作都是在编译numpy
代码中完成的。
执行矩阵乘法(以及相关的 linalg 求解器(时会更快。 对于大多数其他操作(包括初始化(,它们比等效的密集代码慢。 当问题太大时,它们也很有价值。