2017-01-25 18 views
3

У меня есть массив A, форма которого (N, N, K) и я хотел бы, чтобы вычислить другой массив B с той же формой, где B[:, :, i] = np.linalg.inv(A[:, :, i]).Вычисление обратной 2D-массивов вдоль третьей оси в 3D массив без петель

Как решения, я вижу map и for петель, но мне интересно, если 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]) 

с map:

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

ответ

4

Для обратимой матрицы M мы имеем inv(M).T == inv(M.T) (транспонированное обратный равно обратную величину транспонированного).

С np.linalg.inv является broadcastable, ваша проблема может быть решена просто перенося A, называя inv и перенося результат:

B = np.linalg.inv(A.T).T 

Например:

>>> 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]]]) 

Вы можете проверить значения B соответствуют инверсиям массивов в A, как ожидалось:

>>> all(np.allclose(B[:, :, i], np.linalg.inv(A[:, :, i])) for i in range(K)] 
True 
+0

Ничего себе, я бы никогда не догадался, что 'inv' был доступен для трансляции, но теперь, когда я действительно об этом думаю, почему бы и нет! Хорошая работа, сэр/мадам! –

+0

Действительно, я слишком быстро прочитал документацию 'inv'! – floflo29