numpy教程:numpy基本資料型別及多維陣列元素存取
NumPy介紹
Numpy(讀作num-pie)是Python中的一個矩陣計算包,功能類似於MATLAB的矩陣計算。
標準安裝的Python中用列表(list)儲存一組值,可以用來當作陣列使用,不過由於列表的元素可以是任何物件,因此列表中所儲存的是物件的指標。這樣為了儲存一個簡單的[1,2,3],需要有3個指標和三個整數物件。對於數值運算來說這種結構顯然比較浪費記憶體和CPU計算時間。
此外Python還提供了一個array模組,array物件和列表不同,它直接儲存數值,和C語言的一維陣列比較類似。但是由於它不支援多維,也沒有各種運算函式,因此也不適合做數值運算。
NumPy的誕生彌補了這些不足,NumPy提供了兩種基本的物件:ndarray(N-dimensional array object)和ufunc(universal function object)。ndarray(下文統一稱之為陣列)是儲存單一資料型別的多維陣列(同c語言陣列直接儲存數值
在Python中使用help幫助
>>> import numpy>>> help(numpy.argsort)
Numpy中array和ndarray的區別
np.array
is just a convenience function to create an ndarray
, it is not a class itself.
You can also create an array using np.ndarray
, but it is not the recommended way. From the docstring of np.ndarray
Arrays should be constructed using array
, zeros
orempty
... The parameters given here refer to a low-level method (ndarray(...)
) for instantiating an array.
where can I find the implementations in the numpy source code?
1 Most of the meat of the implementation is in C code, here in multiarray
NumPy中的資料型別
對於科學計算來說,Python中自帶的整型、浮點型和複數型別遠遠不夠,因此NumPy中添加了許多資料型別。
Numpy中基礎的資料型別是np.dtype類的物件.
需要指定所用資料型別的場合, 比如新生成陣列時, 一般都會有個可選引數叫dtype (注意看上面示例). 這個引數可以接受真正的np.dtype物件, 也可以很聰明地直接接收普通的標量型別, 也可以接收各種型別的字串表示(注意看下面那個大列表裡的字元簡稱). 其預設值一般都是python原生的那種float型(一般就相當於C裡面的double).
類似於其他語言的int, float, double之類的標量型別並不是np.dtype型別物件, 但可以用它來構造np.dtype物件. 比如用Python原生的float型來構造:my_type = np.dtype(float)
numpy缺失值的表示(None, np.NaN, np.NaT, pd.NaT)
NaN: not a number, NaN is the default missing value marker forreasons of computational speed and convenience, we need to be able to easilydetect this value with data of different types: floating point, integer,boolean, and general object.
None: treats None like np.nan. In many cases, however, the Python None will arise and we wish to also consider that “missing” or “null”.
NaT: Datetimes, For datetime64[ns] types, NaT represents missing values. This is a pseudo-native sentinel value that can be represented by numpy in a singular dtype (datetime64[ns]). pandas objects provide intercompatibility between NaT and NaN.
inf: Prior to version v0.10.0 inf and -inf were also considered to be “null” in computations. This is no longer the case by default; use the mode.use_inf_as_null option to recover it.
Note: numpy缺失值的判斷要用np.isnan(),而不能使用a[0] == np.NaN.[numpy教程:邏輯函式Logic functions ]
numpy資料型別
Numpy中提供了更細緻的標量型別, 見下表,這些基礎的標量型別不是np.dtype物件.
每一個numpy內建的資料型別都有一個特徵碼,它能唯一標識資料型別:
採用特徵碼來表示資料型別時,特徵碼來表示資料型別時,第一個字元指明資料的種類,其餘字元指明每一種資料型別的位元組( 對於字串來說,該指明字元中字元數)。其中資料 型別的位元組數必須與某一個 numpy內建的型別相匹配,否則將會丟擲異常。
np.型別名 | 對應於別的語言的型別 | 字元簡稱 |
Booleans | ||
np.bool_ | Python bool | '?' |
np.bool8 | 8 bit bool | |
Int | ||
np.byte | C char | 'b' |
np.short | C short | 'h' |
np.intc | C int | 'i' #int32 |
np.int_ | Python int | 'l' |
np.longlong | C long long | 'q' |
np.intp | 用作指標?? | 'p' |
np.int8 np.int16 np.int32 np.int64 | 特定長度 | |
Unsigned Int | ||
np.ubyte | C unsigned char | 'B' |
np.ushort | C unsigned short | 'H' |
np.uintc | C unsigned int | 'I' |
np.uint_ | Python unsigned int | 'L' |
np.ulonglong | C unsigned long long | 'Q' |
np.uintp | 用作指標?? | 'P' |
np.uint8 np.uint16 np.uint32 np.uint64 | 特定長度 | |
Float | ||
np.single | C float | 'f' |
np.double | C double | |
np.float_ | Python float | 'd' |
np.longfloat | C long float | 'g' |
np.float32 np.float64 np.float96 np.float128 | 特定長度 後兩個依賴於平臺 | |
Complex(複數) | ||
np.csingle | 'F' | |
np.complex_ | Python complex | 'D' |
np.clongfloat | 'G' | |
np.complex64 np.complex128 np.complex192 np.complex256 | 特定長度 後兩個依賴於平臺 | |
Any Python Object | ||
np.object_ | 儲存的實際是引用 | 'O' |
np.str_ | Python str | 'S#' # = number #控制每個str長度 |
np.unicode_ | Python unicode | 'U#' |
void | 'V#' |
NumPy中的基本資料型別取值範圍
名稱 | 描述 |
bool | 用一個Bit儲存的布林型別(True或False) |
inti | 由所在平臺決定其大小的整數(一般為int32或int64) |
int8 | 一個位元組大小,-128 至 127 |
int16 | 整數,-32768 至 32767 |
int32 | 整數,-2 ** 31 至 2 ** 32 -1 |
int64 | 整數,-2 ** 63 至 2 ** 63 - 1 |
uint8 | 無符號整數,0 至 255 |
uint16 | 無符號整數,0 至 65535 |
uint32 | 無符號整數,0 至 2 ** 32 - 1 |
uint64 | 無符號整數,0 至 2 ** 64 - 1 |
float16 | 半精度浮點數:16位,正負號1位,指數5位,精度10位 |
float32 | 單精度浮點數:32位,正負號1位,指數8位,精度23位 |
float64或float | 雙精度浮點數:64位,正負號1位,指數11位,精度52位 |
complex64 | 複數,分別用兩個32位浮點數表示實部和虛部 |
complex128或complex | 複數,分別用兩個64位浮點數表示實部和虛部 |
[Data type objects (dtype)]
多維陣列ndarray記憶體結構
下面讓我們來看看ndarray陣列物件是如何在記憶體中儲存的。如下圖所示,關於陣列的描述資訊儲存在一個數據結構中,這個結構引用兩個物件:一塊用於儲存資料的儲存區域和一個用於描述元素型別的dtype物件。
資料儲存區域儲存著陣列中所有元素的二進位制資料,dtype物件則知道如何將元素的二進位制資料轉換為可用的值。陣列的維數、大小等資訊都儲存在ndarray陣列物件的資料結構中。圖中顯示的是如下陣列的記憶體結構:
>>> a = np.array([[0,1,2],[3,4,5],[6,7,8]], dtype=np.float32) a.strides (12, 4)
strides中儲存的是當每個軸的下標增加1時,資料儲存區中的指標所增加的位元組數。例如圖中的strides為12,4,即第0軸的下標增加1時,資料的地址增加12個位元組:即a[1,0]的地址比a[0,0]的地址要高12個位元組,正好是3個單精度浮點數的總位元組數;第1軸下標增加1時,資料的地址增加4個位元組,正好是單精度浮點數的位元組數。
如果strides中的數值正好和對應軸所佔據的位元組數相同的話,那麼資料在記憶體中是連續儲存的。然而資料並不一定都是連續儲存的,前面介紹過通過下標範圍得到新的陣列是原始陣列的檢視,即它和原始檢視共享資料儲存區域:
>>> b = a[::2,::2] >>> b array([[ 0., 2.], [ 6., 8.]], dtype=float32) >>> b.strides (24, 8)
由於陣列b和陣列a共享資料儲存區,而b中的第0軸和第1軸都是陣列a中隔一個元素取一個,因此陣列b的strides變成了24,8,正好都是陣列a的兩倍。 對照前面的圖很容易看出資料0和2的地址相差8個位元組,而0和6的地址相差24個位元組。
元素在資料儲存區中的排列格式有兩種:C語言格式和Fortan語言格式。在C語言中,多維陣列的第0軸是最上位的,即第0軸的下標增加1時,元素的地址增加的位元組數最多;而Fortan語言的多維陣列的第0軸是最下位的,即第0軸的下標增加1時,地址只增加一個元素的位元組數。在NumPy中,元素在記憶體中的排列預設是以C語言格式儲存的,如果你希望改為Fortan格式的話,只需要給陣列傳遞order="F"引數:
>>> c = np.array([[0,1,2],[3,4,5],[6,7,8]], dtype=np.float32, order="F") >>> c.strides (4, 12)
ndarray陣列維度-橫向量和列向量
{關於numpy陣列維度表示上的區別,numpy多維陣列橫向量和列向量的區別}
zeros([5,]) #返回的是一維列向量
[ 0. 0. 0. 0. 0.] #等價於這樣的矩陣(一維陣列),zeros([5])、zeros(5)以及zeros(5,)
zeros([5, 1]) #返回的是二維列向量 [[ 0.] [ 0.] [ 0.] [ 0.] [ 0.]]
zeros([1, 5]) #二維橫向量
[[ 0. 0. 0. 0. 0.]]
a = array([1,2,3]) #一維列向量 print(a.shape, a) b = array([[1,2,3]]) #二維橫向量 print(b.shape, b) (3,) [1 2 3] (1, 3) [[1 2 3]]
Note:a=np.array([1,2,3]) 由 a.shape知道a是一個列向量,而b=np.array([[1,2,3]])是一個橫向量。
b=arange(1,5) #列向量 print(b.shape, b)
a=array([[1,2,3,4]])#橫向量 print(a.shape, a) print(a+b) (4,) [1 2 3 4] (1, 4) [[1 2 3 4]] [[2 4 6 8]]
Note:
1. 上面的例子沒有說明的,數值就是原來的,沒有變。比較上面知道,基本上橫向量和列向量是可以任意加減的。但是其他的要有一樣的shape才可以。
2.一維列向量的轉置還是本身。
3. 一維列向量(如(3,))在廣播運算中是當做二維行向量(如(1,3))計算的。也就是說(3,)相當於(1,3)。
np.mean(二維向量)
返回的是一個一維列向量
numpy.mean的維度:規範化,x矩陣中xi總是以列向量表示一個數據點,行代表維度(行0代表維度1)A = [[-2. -1. 0. 1. 2.] [-1. 0. -1. 2. 0.] [ 1. 1. 1. -1. -2.]]
col_mean= np.mean(A, 0)
print(col_mean.shape)(5,)[[-1.33333333 -1. 0. 0.33333333 2. ]
[-0.33333333 0. -1. 1.33333333 0. ]
[ 1.66666667 1. 1. -1.66666667 -2. ]]
col_mean = np.mean(A, 0).reshape(1, len(A[0])) print(col_mean.shape) # print(col_mean) A -= col_mean print(A)(1, 5)
[[-1.33333333 -1. 0. 0.33333333 2. ]
[-0.33333333 0. -1. 1.33333333 0. ]
[ 1.66666667 1. 1. -1.66666667 -2. ]]
array元素存取
元素存取的不同方式
下標範圍存取元素
結束索引在這兒是不被包含的!和python中的list的索引相同!但是不同於pandas中的索引是被包含的!!!
陣列元素的存取方法和Python的標準方法相同:
>>> a = np.arange(10) >>> a[5] # 用整數作為下標可以獲取陣列中的某個元素 5 >>> a[3:5] # 用範圍作為下標獲取陣列的一個切片,包括a[3]不包括a[5] array([3, 4]) >>> a[:5] # 省略開始下標,表示從a[0]開始 array([0, 1, 2, 3, 4]) >>> a[:-1] # 下標可以使用負數,表示從陣列後往前數 array([0, 1, 2, 3, 4, 5, 6, 7, 8]) >>> a[2:4] = 100,101 # 下標還可以用來修改元素的值 >>> a array([ 0, 1, 100, 101, 4, 5, 6, 7, 8, 9]) >>> a[1:-1:2] # 範圍中的第三個引數表示步長,2表示隔一個元素取一個元素 array([ 1, 101, 5, 7]) >>> a[::-1] # 省略範圍的開始下標和結束下標,步長為-1,整個陣列頭尾顛倒 array([ 9, 8, 7, 6, 5, 4, 101, 100, 1, 0]) >>> a[5:1:-2] # 步長為負數時,開始下標必須大於結束下標 array([ 5, 101])
numpy陣列下標是可以越界的!
>>> b
array([1, 2, 3, 4, 5, 6])
>>> b[1:30309]
array([2, 3, 4, 5, 6])
如果越界了,會自動檢測,只返回到結尾的資料。
和Python的列表序列不同,通過下標範圍獲取的新的陣列是原始陣列的一個檢視,它與原始陣列共享同一塊資料空間。
>>> b = a[3:7] # 通過下標範圍產生一個新的陣列b,b和a共享同一塊資料空間 >>> b array([101, 4, 5, 6]) >>> b[2] = -10 # 將b的第2個元素修改為-10 >>> b array([101, 4, -10, 6]) >>> a # a的第5個元素也被修改為10 array([ 0, 1, 100, 101, 4, -10, 6, 7, 8, 9])
除了使用下標範圍存取元素之外,NumPy還提供了兩種存取元素的高階方法。
使用整數序列
當使用整數序列對陣列元素進行存取時,將使用整數序列中的每個元素作為下標,整數序列可以是列表或者陣列。使用整數序列作為下標獲得的陣列不和原始陣列共享資料空間。
>>> x = np.arange(10,1,-1) >>> x array([10, 9, 8, 7, 6, 5, 4, 3, 2]) >>> x[[3, 3, 1, 8]] # 獲取x中的下標為3, 3, 1, 8的4個元素,組成一個新的陣列;python自帶的list不能這麼做 array([7, 7, 9, 2]) >>> b = x[np.array([3,3,-3,8])] #下標可以是負數 >>> b[2] = 100 >>> b array([7, 7, 100, 2]) >>> x # 由於b和x不共享資料空間,因此x中的值並沒有改變 array([10, 9, 8, 7, 6, 5, 4, 3, 2]) >>> x[[3,5,1]] = -1, -2, -3 # 整數序列下標也可以用來修改元素的值 >>> x array([10, -3, 8, -1, 6, -2, 4, 3, 2])
使用布林陣列
當使用布林陣列b作為下標存取陣列x中的元素時,將收集陣列x中所有在陣列b中對應下標為True的元素,使用布林陣列作為下標獲得的陣列不和原始陣列共享資料空間。
注意這種方式只對應於布林陣列(np.array([True, False, ....])),不能使用布林列表([True, False, ....])。
使用布林陣列進行numpy陣列值的替換:a[ a == 3] = 4; ll_array[np.array(labels_list) == label] = km_model.centers[label]
>>> x = np.arange(5,0,-1) >>> x array([5, 4, 3, 2, 1]) >>> x[np.array([True, False, True, False, False])] >>> # 布林陣列中下標為0,2的元素為True,因此獲取x中下標為0,2的元素 array([5, 3]) >>> x[[True, False, True, False, False]] >>> # 如果是布林列表,則把True當作1, False當作0,按照整數序列方式獲取x中的元素 array([4, 5, 4, 5, 5]) >>> x[np.array([True, False, True, True])] >>> # 布林陣列的長度不夠時,不夠的部分都當作False array([5, 3, 2]) >>> x[np.array([True, False, True, True])] = -1, -2, -3 >>> # 布林陣列下標也可以用來修改元素 >>> x array([-1, 4, -2, -3, 1])
布林陣列一般不是手工產生,而是使用布林運算的ufunc函式產生,關於ufunc函式請參照 ufunc運算 一節。
>>> x array([ 0.72223939, 0.921226 , 0.7770805 , 0.2055047 , 0.17567449, 0.95799412, 0.12015178, 0.7627083 , 0.43260184, 0.91379859]) >>> x[x>0.5] array([ 0.72223939, 0.921226 , 0.7770805 , 0.95799412, 0.7627083 , 0.91379859])
多維陣列切片操作
多維陣列的存取和一維陣列類似,因為多維陣列有多個軸,因此它的下標需要用多個值來表示,NumPy採用組元(tuple)作為陣列的下標。如下圖所示,a為一個6x6的陣列,圖中用顏色區分了各個下標以及其對應的選擇區域。
雖然我們經常在Python中用圓括號將組元括起來,但是其實組元的語法定義只需要用逗號隔開即可,不需要圓括號,例如 x,y=y,x 就是用組元交換變數值的一個例子。如何建立這個陣列: 陣列a實際上是一個加法表,縱軸的值為0, 10, 20, 30, 40, 50;橫軸的值為0, 1, 2, 3, 4, 5。縱軸的每個元素都和橫軸的每個元素求和,就得到圖中所示的陣列a。你可以用下面的語句建立它,至於其原理我們將在後面的章節進行討論:
>>> np.arange(0, 60, 10).reshape(-1, 1) + np.arange(0, 6) array([[ 0, 1, 2, 3, 4, 5], [10, 11, 12, 13, 14, 15], [20, 21, 22, 23, 24, 25], [30, 31, 32, 33, 34, 35], [40, 41, 42, 43, 44, 45], [50, 51, 52, 53, 54, 55]])
多維陣列同樣也可以使用整數序列和布林陣列進行存取
假設x是一個二維陣列,inds是整數序列的陣列array型別表示的下標:
如果inds是一個一維array,則x[inds]返回的是一個二維array;但是如果inds是一個二維array,則x[inds]返回的是一個三維array。
import numpy as np x = np.array([[1, 2, 3], [2, 3, 4]]) inds = np.array([0, 1]) print(x[inds].shape, '\n', x[inds]) inds = np.array([[0, 1]]) print(x[inds].shape, '\n', x[inds])
(2, 3)
[[1 2 3]
[2 3 4]]
(1, 2, 3)
[[[1 2 3]
[2 3 4]]]
使用整數序列和布林陣列訪問多維陣列中的元素
a[(0,1,2,3,4),(1,2,3,4,5)] : 用於存取陣列的下標和仍然是一個有兩個元素的組元,組元中的每個元素都是整數序列,分別對應陣列的第0軸和第1軸。從兩個序列的對應位置取出兩個整陣列成下標: a[0,1], a[1,2], ..., a[4,5]。
a[3:, [0, 2, 5]] : 下標中的第0軸是一個範圍,它選取第3行之後的所有行;第1軸是整數序列,它選取第0, 2, 5三列。
a[mask, 2] : 下標的第0軸是一個布林陣列,它選取第0,2,5行;第1軸是一個整數,選取第2列。
結構陣列
在C語言中我們可以通過struct關鍵字定義結構型別,結構中的欄位佔據連續的記憶體空間,每個結構體佔用的記憶體大小都相同,因此可以很容易地定義結構陣列。和C語言一樣,在NumPy中也很容易對這種結構陣列進行操作。只要NumPy中的結構定義和C語言中的定義相同,NumPy就可以很方便地讀取C語言的結構陣列的二進位制資料,轉換為NumPy的結構陣列。
假設我們需要定義一個結構陣列,它的每個元素都有name, age和weight欄位。在NumPy中可以如下定義:
import numpy as np persontype = np.dtype({ 'names':['name', 'age', 'weight'], 'formats':['S32','i', 'f']}) a = np.array([("Zhang",32,75.5),("Wang",24,65.2)], dtype=persontype)
我們先建立一個dtype物件persontype,通過其字典引數描述結構型別的各個欄位。字典有兩個關鍵字:names,formats。每個關鍵字對應的值都是一個列表。names定義結構中的每個欄位名,而formats則定義每個欄位的型別:
S32 : 32個位元組的字串型別,由於結構中的每個元素的大小必須固定,因此需要指定字串的長度
i : 32bit的整數型別,相當於np.int32
f : 32bit的單精度浮點數型別,相當於np.float32
然後我們呼叫array函式建立陣列,通過關鍵字引數 dtype=persontype, 指定所建立的陣列的元素型別為結構persontype。執行上面程式之後,我們可以在IPython中執行如下的語句檢視陣列a的元素型別
>>> a.dtype dtype([('name', '|S32'), ('age', '<i4'), ('weight', '<f4')])
這裡我們看到了另外一種描述結構型別的方法: 一個包含多個組元的列表,其中形如 (欄位名, 型別描述) 的組元描述了結構中的每個欄位。型別描述前面為我們添加了 "|", "<" 等字元,這些字元用來描述欄位值的位元組順序:
| : 忽視位元組順序
< : 低位位元組在前
> : 高位位元組在前
結構陣列的存取方式和一般陣列相同,通過下標能夠取得其中的元素,注意元素的值看上去像是組元,實際上它是一個結構:
>>> a[0] ('Zhang', 32, 75.5) >>> a[0].dtype dtype([('name', '|S32'), ('age', '<i4'), ('weight', '<f4')])
a[0]是一個結構元素,它和陣列a共享記憶體資料,因此可以通過修改它的欄位,改變原始陣列中的對應欄位:
>>> c = a[1] >>> c["name"] = "Li" >>> a[1]["name"] "Li"
結構像字典一樣可以通過字串下標獲取其對應的欄位值:
>>> a[0]["name"] 'Zhang'
我們不但可以獲得結構元素的某個欄位,還可以直接獲得結構陣列的欄位,它返回的是原始陣列的檢視,因此可以通過修改b[0]改變a[0]["age"]:
>>> b=a[:]["age"] # 或者a["age"] >>> b array([32, 24]) >>> b[0] = 40 >>> a[0]["age"] 40
通過呼叫a.tostring或者a.tofile方法,可以直接輸出陣列a的二進位制形式:
>>> a.tofile("test.bin")
利用下面的C語言程式可以將test.bin檔案中的資料讀取出來。
記憶體對齊
C語言的結構體為了記憶體定址方便,會自動的新增一些填充用的位元組,這叫做記憶體對齊。例如如果把下面的name[32]改為name[30]的話,由於記憶體對齊問題,在name和age中間會填補兩個位元組,最終的結構體大小不會改變。因此如果numpy中的所配置的記憶體大小不符合C語言的對齊規範的話,將會出現資料錯位。為了解決這個問題,在建立dtype物件時,可以傳遞引數align=True,這樣numpy的結構陣列的記憶體對齊和C語言的結構體就一致了。
#include <stdio.h> struct person { char name[32]; int age; float weight; }; struct person p[2]; void main () { FILE *fp; int i; fp=fopen("test.bin","rb"); fread(p, sizeof(struct person), 2, fp); fclose(fp); for(i=0;i<2;i++) printf("%s %d %f", p[i].name, p[i].age, p[i].weight); getchar(); }
結構型別中可以包括其它的結構型別,下面的語句建立一個有一個欄位f1的結構,f1的值是另外一個結構,它有欄位f2,其型別為16bit整數。
>>> np.dtype([('f1', [('f2', np.int16)])]) dtype([('f1', [('f2', '<i2')])])
當某個欄位型別為陣列時,用組元的第三個引數表示,下面描述的f1欄位是一個shape為(2,3)的雙精度浮點陣列:
>>> np.dtype([('f0', 'i4'), ('f1', 'f8', (2, 3))]) dtype([('f0', '<i4'), ('f1', '<f8', (2, 3))])
用下面的字典引數也可以定義結構型別,字典的關鍵字為結構中欄位名,值為欄位的型別描述,但是由於字典的關鍵字是沒有順序的,因此欄位的順序需要在型別描述中給出,型別描述是一個組元,它的第二個值給出欄位的位元組為單位的偏移量,例如age欄位的偏移量為25個位元組:
>>> np.dtype({'surname':('S25',0),'age':(np.uint8,25)}) dtype([('surname', '|S25'), ('age', '|u1')])
[http://mp.weixin.qq.com/s?__biz=MjM5NzU0MzU0Nw==&mid=204507794&idx=2&sn=56f4950a7399af1b1bf69e194d55a48a&scene=1&from=singlemessage&isappinstalled=0#rd]
掩碼陣列
{表示的是不完整的資料或是含有無效值的資料}
>>> import numpy.ma as ma
>>> b
array([2, 3, 3, 0, 1, 4, 2, 4])
>>> mask=b<3
>>> mx=ma.array(b,mask=mask)
>>> mx
masked_array(data = [-- 3 3 -- -- 4 -- 4],
mask = [ True False False True True False True False],fill_value = 999999)
點(…)
代表許多產生一個完整的索引元組必要的分號。如果x是秩為5的陣列(即它有5個軸),那麼:
x[1,2,…] 等同於 x[1,2,:,:,:],x[…,3] 等同於 x[:,:,:,:,3]
x[4,…,5,:] 等同 x[4,:,:,5,:].
>>> c = array( [ [[ 0, 1, 2], # a 3D array (two stacked 2D arrays)
... [ 10, 12, 13]],
...
... [[100,101,102],
... [110,112,113]] ] )
>>> c.shape
(2, 2, 3)
>>> c[1,...] # same as c[1,:,:] or c[1]
array([[100, 101, 102],
[110, 112, 113]])
>>> c[...,2] # same as c[:,:,2]
array([[ 2, 13],
[102, 113]])
from:http://blog.csdn.net/pipisorry/article/details/39215089《Python科學計算》
《Tentative NumPy Tutorial》