计算矩阵未成年人的Numpy Routine?

use*_*504 12 python numpy

我有兴趣使用numpy来计算给定方阵的所有未成年人.是否有一种使用数组切片的光滑方式来做到这一点?我想象一个人可以旋转列,删除最后一列,旋转结果矩阵的行并删除最后一行,但我没有在numpy文档中找到任何表明这是可能的.

(问:为什么会这样?答:我有一个相当大的矩阵的长序列{M_n},大约1,000,000 10,000 x 10,000个矩阵,我想计算每个矩阵的行列式.每个矩阵都是通过改变它的前身来获得的.计算序列中第一个矩阵的行列式,然后计算差值det(M_ {n + 1}) - det(M_n),这是变化的乘积,这将快得多.系数及其次要.)

unu*_*tbu 25

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]])
Run Code Online (Sandbox Code Playgroud)

这样可以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]])
Run Code Online (Sandbox Code Playgroud)

所以,你可以使用这样的东西:

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])))]
Run Code Online (Sandbox Code Playgroud)

关于它如何工作:

注意索引数组的形状:

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,)
Run Code Online (Sandbox Code Playgroud)

使用[:,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]
Run Code Online (Sandbox Code Playgroud)

第一个和第二个数组的外观(概念上)如下:

first array:     second array:
[[0 0 0],        [[0, 1, 3],
 [2 2 2],         [0, 1, 3],
 [3 3 3]]         [0, 1, 3]]
Run Code Online (Sandbox Code Playgroud)


Pau*_*ong 6

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)
Run Code Online (Sandbox Code Playgroud)