1. 程式人生 > >numpy中陣列和矩陣的索引方法及不同點

numpy中陣列和矩陣的索引方法及不同點

NumPy中陣列和矩陣有些重要的區別:
NumPy提供了兩個基本的物件:一個N維陣列物件和一個通用函式物件。其它物件都是建構在它們之上的。特別的,矩陣是繼承自NumPy陣列物件的二維陣列物件。像平常在Python中一樣,索引是從0開始的。傳統上我們用矩形的行和列表示一個二維陣列或矩陣,其中二維矩陣或陣列的行方向為第0軸(豎軸),列方向為第1軸(橫軸)。
注:他們的索引一般都採用一維陣列或者布林值組成的陣列,而不採用列表或其他序列!基本的切片使用切片物件或整數。例如,A[:]和M[:]的求值將表現得和Python索引很相似。然而要注意很重要的一點就是NumPy切片陣列不建立資料的副本;切片提供統一資料的檢視。

建立陣列和矩陣用來切片:此處的複製為深複製,A為陣列,M為矩陣

>>> A = arange(12)
>>> A
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
>>> A.shape = (3,4)
>>> M = mat(A.copy())
>>> print type(A),"  ",type(M)

>>> print A
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
>>> print
M [[ 0 1 2 3] [ 4 5 6 7] [ 8 9 10 11]]

重要不同是:

對於陣列:
>>> print A[:,1]; print A[:,1].shape
[1 5 9]
(3,)
對於矩陣:
>>> print M[:,1]; print M[:,1].shape
[[1]
 [5]
 [9]]
(3, 1) 

最後兩個結果的不同:對二維陣列使用一個冒號產生一個一維陣列,然而矩陣產生了一個二維矩陣。例如,一個M[2,:]切片產生了一個形狀為(1,4)的矩陣,相比之下,一個數組的切片總是產生一個最低可能維度11的陣列

。例如,如果C是一個三維陣列,C[…,1]產生一個二維的陣列而C[1,:,1]產生一個一維陣列。

那麼怎樣讓陣列和矩陣得到的切片結果相同呢?
比如說我們想要保留第一行大於1的列。一種方法是建立布林索引:

>>> A[0,:]>1
array([False, False, True, True], dtype=bool)
>>> A[:,A[0,:]>1]
array([[ 2,  3],
       [ 6,  7],
       [10, 11]]) 

就是我們想要的!但是索引矩陣沒這麼方便。

>>> M[0,:]>1
matrix([[False, False, True, True]], dtype=bool)
>>> M[:,M[0,:]>1]
matrix([[2, 3]]) 

這個過程的問題是用“矩陣切片”來切片產生一個矩陣,但是矩陣有個方便的A屬性,它的值是陣列呈現的。所以我們僅僅做以下替代來得到和陣列相同的切片結果:

>>> M[:,M.A[0,:]>1]
matrix([[ 2,  3],
        [ 6,  7],
        [10, 11]]) 

如果我們想要在矩陣兩個方向有條件地切片,我們必須稍微調整策略,代之以:

>>> A[A[:,0]>2,A[0,:]>1]
array([ 6, 11])
>>> M[M.A[:,0]>2,M.A[0,:]>1]
matrix([[ 6, 11]])