在没有循环的3D阵列中计算沿着第三轴的2D阵列的逆

flo*_*o29 7 python arrays numpy linear-algebra vectorization

我有一个A形状的数组,(N, N, K)我想计算另一个B具有相同形状的数组B[:, :, i] = np.linalg.inv(A[:, :, i]).

作为解决方案,我看到mapfor循环,但我想知道是否numpy提供了一个功能来做到这一点(我已经尝试过,np.apply_over_axes但它似乎只能处理1D数组).

for循环:

B = np.zeros(shape=A.shape)
for i in range(A.shape[2]):
    B[:, :, i] = np.linalg.inv(A[:, :, i])
Run Code Online (Sandbox Code Playgroud)

map:

B = np.asarray(map(np.linalg.inv, np.squeeze(np.dsplit(A, A.shape[2])))).transpose(1, 2, 0)
Run Code Online (Sandbox Code Playgroud)

Ale*_*ley 8

对于M我们所拥有的可逆矩阵inv(M).T == inv(M.T)(逆的转置等于转置的倒数).

由于np.linalg.inv是可播放的,只需转置A,调用inv和转置结果即可解决您的问题:

B = np.linalg.inv(A.T).T
Run Code Online (Sandbox Code Playgroud)

例如:

>>> N, K = 2, 3
>>> A = np.random.randint(1, 5, (N, N, K))
>>> A
array([[[4, 2, 3],
        [2, 3, 1]],

       [[3, 3, 4],
        [4, 4, 4]]])

>>> B = np.linalg.inv(A.T).T
>>> B
array([[[ 0.4  , -4.   ,  0.5  ],
        [-0.2  ,  3.   , -0.125]],

       [[-0.3  ,  3.   , -0.5  ],
        [ 0.4  , -2.   ,  0.375]]])
Run Code Online (Sandbox Code Playgroud)

您可以按预期检查B匹配数组反转的值A:

>>> all(np.allclose(B[:, :, i], np.linalg.inv(A[:, :, i])) for i in range(K))
True
Run Code Online (Sandbox Code Playgroud)