2010-10-04 38 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。