我想要一种向量化特征值计算的numpy-sh方式,这样我就可以给它一个矩阵矩阵,它将返回一个相应特征值的矩阵。
例如,在下面的代码中,B是由3x3矩阵A的4个副本组成的块6x6矩阵。 C是我希望看到的输出,即维数(2,2,3)的数组(因为A有3个特征值)。
这当然是一个非常简化的例子,在一般情况下,矩阵A可以有任何大小(尽管它们仍然是正方形),矩阵B不一定由A的副本组成。 ,但不同的A1,A2等(所有相同的尺寸,但包含不同的元素)。
import numpy as np
A = np.array([[0, 1, 0],
[0, 2, 0],
[0, 0, 3]])
B = np.bmat([[A, A], [A,A]])
C = np.array([[np.linalg.eigvals(B[0:3,0:3]),np.linalg.eigvals(B[0:3,3:6])],
[np.linalg.eigvals(B[3:6,0:3]),np.linalg.eigvals(B[3:6,3:6])]])
答案 0 :(得分:4)
编辑:如果你使用的是numpy> = 1.8.0 的版本,那么np.linalg.eigvals
会在您提供的任何数组的最后两个维度上运行,所以如果你将您的输入重新整理为(n_subarrays, nrows, ncols)
数组,您只需拨打eigvals
一次:
import numpy as np
A = np.array([[0, 1, 0],
[0, 2, 0],
[0, 0, 3]])
# the input needs to be an array, since matrices can only be 2D.
B = np.repeat(A[np.newaxis,...], 4, 0)
# for arbitrary input arrays you could do something like:
# B = np.vstack(a[np.newaxis,...] for a in input_arrays)
# but for this to work it will be necessary for each element in
# 'input_arrays' to have the same shape
# eigvals will operate over the last two dimensions of the array and return
# a (4, 3) array of eigenvalues
C = np.linalg.eigvals(B)
# reshape this output so that it matches your original example
C.shape = (2, 2, 3)
如果您的输入数组并非都具有相同的尺寸,例如input_arrays[0].shape == (2, 2)
,input_arrays[1].shape == (3, 3)
等等,您只能在具有匹配尺寸的子集中对此计算进行矢量化。
如果您使用的是较旧版本的numpy ,那么遗憾的是我认为没有办法在多个输入数组上矢量化特征值的计算 - 你只需要循环你在Python中的输入。
答案 1 :(得分:1)
你可以做这样的事情
C = np.array([[np.linalg.eigvals(B[i:i+3, j:j+3])
for i in xrange(0, B.shape[0], 3)]
for j in xrange(0, B.shape[1], 3)])
也许更好的方法是使用https://stackoverflow.com/a/5078155/1352250中的block_view
函数:
B_blocks = block_view(B)
C = np.array([[np.linalg.eigvals(m) for m in v] for v in B_blocks])
<强>更新强>
正如ali_m指出的那样,这种方法是一种语法糖形式,不会减少大量调用eigvals
所产生的开销。虽然如果应用的每个矩阵都很大,这个开销应该很小,但对于OP感兴趣的6x6矩阵,它并不是微不足道的(参见下面的注释;根据ali_m,可能有三个因子)上面给出的版本与他发布的使用Numpy&gt; = 1.8.0的版本之间的差异。