Numpy рутина для вычислительной матрицы несовершеннолетних?

Я заинтересован в использовании NumPy для вычисления всех миноров данной квадратной матрицы. Есть ли удобный способ использования нарезки массивов для этого? Я представляю, что можно вращать столбцы, удалять последний столбец, вращать строки полученной матрицы и удалять последнюю строку, но я не нашел ничего в пустой документации, которая бы указала, что это возможно.

(В: Зачем это? A: У меня есть длинная последовательность {M_n} довольно больших матриц, примерно 10000000000000000, и я хочу вычислить определитель каждой матрицы. Каждая матрица получается из предшественника путем изменения только один коэффициент. Будет гораздо быстрее вычислить определитель первой матрицы в последовательности, а затем вычислить разницу det (M_ {n + 1}) - det (M_n), которая является произведением измененного коэффициент и его минор.)

Ответы на вопрос(3)

Ответ от unutbu уже великолепен, и для оптимизации алгоритма ответ @ ev-br поставил меня в интересное путешествие.

Мой ответ ниже на вопрос просто для того, чтобы сделать его более понятным из намерений.

import numpy as np

arr = np.random.normal(0,1,(4,4))



def matrix_minor(arr, i, j):
    return np.delete(np.delete(arr,i,axis=0), j, axis=1)

# tests
arr

matrix_minor(arr, 0, 0)

matrix_minor(arr, 0, 1)
Решение Вопроса
In [34]: arr=np.random.random((4,4))

In [35]: arr
Out[35]: 
array([[ 0.00750932,  0.47917318,  0.39813503,  0.11755234],
       [ 0.30330724,  0.67527229,  0.71626247,  0.22526589],
       [ 0.5821906 ,  0.2060713 ,  0.50149411,  0.0328739 ],
       [ 0.42066294,  0.88529916,  0.09179092,  0.39389844]])

Это дает несовершеннолетнимarrс удалением 1-го ряда и 2-го столбца:

In [36]: arr[np.array([0,2,3])[:,np.newaxis],np.array([0,1,3])]
Out[36]: 
array([[ 0.00750932,  0.47917318,  0.11755234],
       [ 0.5821906 ,  0.2060713 ,  0.0328739 ],
       [ 0.42066294,  0.88529916,  0.39389844]])

Итак, вы можете использовать что-то вроде этого:

def minor(arr,i,j):
    # ith row, jth column removed
    return arr[np.array(list(range(i))+list(range(i+1,arr.shape[0])))[:,np.newaxis],
               np.array(list(range(j))+list(range(j+1,arr.shape[1])))]

Относительно того, как это работает:

Обратите внимание на форму индексных массивов:

In [37]: np.array([0,2,3])[:,np.newaxis].shape
Out[37]: (3, 1)

In [38]: np.array([0,1,3]).shape
Out[38]: (3,)

Использование[:,np.newaxis] было просто дать первому массиву форму (3,1).

Поскольку это массивы numpy (вместо, скажем, слайсов), numpy использует так называемую «причудливую» индексацию. Правила для необычной индексации требуют, чтобы форма двух массивов была одинаковой, или, если они не одинаковы, использовать широковещательную передачу, чтобы «накачать» фигуры так, чтобы они совпадали.

В этом случае форма второго массива (3,) накачивается до (1,3). Но (3,1) и (1,3) не совпадают, поэтому (3,1) накачано до (3,3) и (1,3) накачано до (3,3).

Ах, наконец, два массива numpy имеют (после трансляции) одинаковую форму (3,3).

Numpy принимаетarr[<array of shape (3,3)>, <array of shape (3,3)>] и возвращает массив формы (не удивительно) (3,3).

(I, j) -й элемент возвращаемого массива будет

arr[(i,j)-th element of first array, (i,j)-th element of second array]

где первый и второй массивы выглядят (концептуально) так:

first array:     second array:
[[0 0 0],        [[0, 1, 3],
 [2 2 2],         [0, 1, 3],
 [3 3 3]]         [0, 1, 3]]
 unutbu04 окт. 2010 г., 21:30
Не волнуйтесь; рад, что это полезно.
 user150404 окт. 2010 г., 21:27
Это заслуживает голосов, но мне не хватает репутации.
 unutbu16 окт. 2018 г., 22:25
@ Скуби-Ду: Спасибо за исправление.
 user150404 окт. 2010 г., 21:16
Slick. Я приму это, как только выясню, почему это работает. Спасибо!
 The AI Architect16 окт. 2018 г., 00:29
Чтобы добавить вызовы range () в Python 3, нужно сначала обернуть их каждый в список, например,list(range(i)) + list(range(i+1, arr.shape[0]))

Если вы изменяете только один элемент матрицы за раз, вам, вероятно, лучше использовать формулы типа Шермана-Моррисона, (вики): таким образом, у вас есть сложность N ^ 2 вместо N ^ 3.

Ваш ответ на вопрос