2016-06-12 146 views
2

可以說有3行3列的numpy矩陣。找到第一個對角線很容易,它是一種方法。如何查找二維矩陣的兩個對角線?

用下面的矩陣:

[[0,3,6] 

[0,4,9] 

[0,1,9]] 

使用此代碼:

import numpy 
matrix.diagonals() 
[0, 4, 9] 

我怎樣才能得到相反的對角線?例如上述矩陣我想它返回:

[6, 4, 0] 

回答

1

我想這會做到這一點:

In [29]: mm 
Out[29]: 
matrix([[0, 3, 6], 
     [0, 4, 9], 
     [0, 1, 9]]) 

In [30]: np.fliplr(mm) 
Out[30]: 
matrix([[6, 3, 0], 
     [9, 4, 0], 
     [9, 1, 0]]) 

In [31]: mm.diagonal() 
Out[31]: matrix([[0, 4, 9]]) 

In [33]: np.fliplr(mm).diagonal() 
Out[33]: matrix([[6, 4, 0]]) 
1

您可以進行如下操作:
(1)逆轉矩陣( 2)得到的對角線,(3)反向對角線

import numpy 

a = numpy.matrix([[0, 3, 6], [0, 4, 9], [0, 1, 9]]) 
print(numpy.diag(a)) 
print(numpy.diag(a[::-1])[::-1]) 

輸出:

[0 4 9] 
[6 4 0] 
1
In [240]: M=np.arange(9).reshape(3,3) 

的主對角線爲M[i,j] for i==j,我們可以得到先進的索引與同一陣列i和j

In [241]: i=np.arange(3) 

In [242]: M[i,i] 
Out[242]: array([0, 4, 8]) 

,並通過反轉j的順序,我們得到的另一條對角線

In [243]: M[i,i[::-1]] 
Out[243]: array([2, 4, 6]) 

我懷疑,對於大型陣列,扭轉這樣的指數比翻轉矩陣更快。但我們必須確保一些時間。

===========

糟糕,我錯了。 M.diagonal()比我的顯式索引快得多。對於N=1000

In [259]: timeit M.diagonal();np.fliplr(M).diagonal() 
100000 loops, best of 3: 3.63 µs per loop 

In [260]: timeit i=np.arange(N);mm=M[i,i],M[i,i[::-1]] 
10000 loops, best of 3: 51.3 µs per loop 
3

達到此目的的最快方法是使用步幅。你的陣列有一個.strides屬性,它會告訴你多少字節你必須在內存跳到才能到下一個項目中的每個維度:

>>> a = np.array([[0, 3, 6], [0, 4, 9], [0, 1, 9]]) 
>>> a.strides 
(24, 8) 

對於你要跳到一行加上正常的向對角線一列,用於反向對角線,行減去柱:

>>> a.strides[0] + a.strides[1] 
32 
>>> a.strides[0] - a.strides[1] 
16 

現在可以construct從相同的存儲器緩衝器的陣列作爲原始陣列,但用新的跨距(和非零偏移從反向對角線案例的第一行的最後一列開始):

>>> np.ndarray(shape=min(a.shape), dtype=a.dtype, buffer=a, 
...   offset=0, strides=a.strides[0]+a.strides[1]) 
array([0, 4, 9]) 
>>> np.ndarray(shape=min(a.shape), dtype=a.dtype, buffer=a, 
...   offset=a.strides[1] * (a.shape[1] - 1), 
...   strides=a.strides[0]+a.strides[1]) 
array([6, 4, 0]) 

這些實際上是視圖到原始數組的內存,即如果您修改其內容,原始數組也會改變,所以實際上沒有內存分配或複製進行,只是設置包含的對象,所以它會盡可能快地得到。