2010-10-04 66 views
7

我有兴趣使用numpy来计算给定矩形矩阵的所有未成年人。有没有使用数组切片来做到这一点?我想象一下,可以旋转列,删除最后一列,旋转结果矩阵的行并删除最后一行,但是我没有在numpy文档中找到任何表明这是可能的东西。 (Q:为什么会这样?答:我有一个相当大矩阵的长序列{M_n},大约有1,000,000个10,000×10,000矩阵,我想计算每个矩阵的行列式,每个矩阵都是从它的(M_ {n + 1}) - det(M_n),这是计算序列中第一个矩阵的行列式的速度要快很多, 。改变的系数和它的次要的产品)用于计算矩阵未成年人的Numpy例程?

回答

17
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次要,其中移除了第一行和第二列:

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(range(i)+range(i+1,arr.shape[0]))[:,np.newaxis], 
       np.array(range(j)+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]] 
+0

油滑。我会尽快理解它为什么会起作用。谢谢! – user1504 2010-10-04 19:16:03

+0

这值得赞扬,但我没有足够的声望。 – user1504 2010-10-04 19:27:05

+0

不用担心;很高兴这很有帮助。 – unutbu 2010-10-04 19:30:13

1

如果你只改变矩阵的一个元素,你最好使用谢尔曼 - 莫里森类型公式,(wiki):这样,你的复杂度就是N^2而不是N^3。