Инвертировать ненулевую подматрицу в numpy, возвращая матрицу исходной формы - PullRequest
0 голосов
/ 15 октября 2019

У меня есть матрица с некоторыми строками и столбцами, равными нулю, поэтому она не обратима.
Мне нужно получить инверсию ненулевой подматрицы, чтобы инверсия имела ту же структуру, что и исходнаяmatrix.
Ожидаемое поведение будет примерно таким:

>>>test
array([[1, 0, 0, 2],
       [0, 0, 0, 0],
       [0, 0, 0, 0],
       [3, 0, 0, 4]])
>>>get_nonzero(test)
array([[1, 2],
       [3, 4]])
>>>np.linalg.inv(nonzero)
array([[-2. ,  1. ],
       [ 1.5, -0.5]])
>>>restore_shape(inv_matrix)
array([[-2. ,  0. ,  0. ,  1. ],
       [ 0. ,  0. ,  0. ,  0. ],
       [ 0. ,  0. ,  0. ,  0. ],
       [ 1.5,  0. ,  0. , -0.5]])

Возможно, уместно, чтобы я изначально получал матрицу test, обнуляя строки и столбцы некоторой исходной матрицы со всеми элементами, отличными от нуляс логическим индексированием вроде:

>>>bool_index
array([False,  True,  True, False])
>>>original[bool_index, :] = 0
>>>original[:, bool_index] = 0
>>>original
array([[1, 0, 0, 2],
       [0, 0, 0, 0],
       [0, 0, 0, 0],
       [3, 0, 0, 4]])

Я добился получения ненулевой подматрицы из исходной матрицы, сначала преобразовав ее в pandas DataFrame и индексировав с помощью логических массивов с .loc, например:

>>>pd.DataFrame(original).loc[~bool_index, ~bool_index].values
array([[1, 2],
       [3, 4]])

Однако я не уверен, как мне эффективно восстановить инвертированный массив в исходную форму.

1 Ответ

0 голосов
/ 15 октября 2019

Чтобы использовать функцию форматирования, которую вы предлагаете, и предполагая, что ваша входная матрица может привести к N * N матрице, следующие работы:

import numpy as np

def get_nonzero(t1):
    t2 = t1[t1 != 0]
    size = int(np.sqrt(len(t2)))

    return t2.reshape(size, size)

def restore_shape(t1, t3):

    t4 = np.zeros(t1.shape)
    idx_non_zeros = np.nonzero(t1)

    for i, elt in enumerate(t3.flatten()):
        t4[idx_non_zeros[0][i], idx_non_zeros[1][i]] = elt

    return t4

t1 = np.array([[1, 0, 0, 2],
               [0, 0, 0, 0],
               [0, 0, 0, 0],
               [3, 0, 0, 4]])

t2 = get_nonzero(t1)
t3 = np.linalg.inv(t2)
t4 = restore_shape(t1, t3)

Но, как предлагается в комментариях, np.linalg.pinv(t1) - это многоболее элегантный и эффективный.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...