用人話說 Numpy – 2/13 陣列Array
NumPy 的主要特色就是 array 物件類別。陣列類似於 Python 的列表 list ,除了陣列內的每個元素都要是相同的類型,通常是整數 int 或是浮點數 float 。陣列使得操作巨大的數值可以很快速,並且比 list 更有效率。
陣列可以從 list 建立
>>> a = np.array([1, 4, 5, 8], float) >>> a array([ 1., 4., 5., 8.]) >>> type(a) <type 'numpy.ndarray'>
這裡的 array 函數接收了兩個參數:第一個是要轉換成陣列的列表,第二個是每一個成員的類型。陣列的元素是可以訪問的,可以切片的,可以操作的。
>>> a[:2] array([ 1., 4.]) >>> a[3] 8.0 >>> a[0] = 5. >>> a array([ 5., 4., 5., 8.])
陣列可以是多維的。跟列表不同,陣列的不同維度用逗號在括號內分隔。以下是一個二維陣列(也叫矩陣)的範例
>>> a = np.array([[1, 2, 3], [4, 5, 6]], float) >>> a array([[ 1., 2., 3.], [ 4., 5., 6.]]) >>> a[0,0] 1.0 >>> a[0,1] 2.0
陣列的切片在操作多維的陣列時跟處理一般陣列時一樣,陣列像是通過一個過濾器一樣,使過濾後的每個切片都是指定規範的維度。使用符號”:”
在一個維度上過濾該維度的所有內容
>>> a = np.array([[1, 2, 3], [4, 5, 6]], float) >>> a[1,:] array([ 4., 5., 6.]) >>> a[:,2] array([ 3., 6.]) >>> a[-1:,-2:] array([[ 5., 6.]])
屬性 shape 會返回陣列的每一維的數量,返回的型態是 tuple 。
>>> a.shape (2, 3)
屬性 dtype 返回陣列內的類型
>>> a.dtype dtype('float64')
這裡顯示的 float64 是數值類型,NumPy 用來存放雙精度(8-byte)的實數,像是 Python 裡的 float 類型。
當函數 len 用在陣列時,會返回第一個維度的長度(數量)
>>> a = np.array([[1, 2, 3], [4, 5, 6]], float) >>> len(a) 2
使用 in 語句,可以用來測試一個值是不是存在陣列之內
>>> a = np.array([[1, 2, 3], [4, 5, 6]], float) >>> 2 in a True >>> 0 in a False
陣列可以用 reshape 方法,以 tuple 做為參數轉換成新的維度。在接下來的範例,把10個元素的一維陣列轉換成二維陣列第一個維度有五個元素,第二個維度有兩個元素
>>> a = np.array(range(10), float) >>> a array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.]) >>> a = a.reshape((5, 2)) >>> a array([[ 0., 1.], [ 2., 3.], [ 4., 5.], [ 6., 7.], [ 8., 9.]]) >>> a.shape (5, 2)
這裡注意 reshape 函數是建立一個新的陣列,而不是修改原始的陣列。
記得 Python 的名稱綁定方式仍然作用於陣列。copy 方法可以用來建立一個新的陣列,如果需要
可以在記憶體內分離複本。
>>> a = np.array([1, 2, 3], float) >>> b = a >>> c = a.copy() >>> a[0] = 0 >>> a array([0., 2., 3.]) >>> b array([0., 2., 3.]) >>> c array([1., 2., 3.])
可以從陣列建立列表
>>> a = np.array([1, 2, 3], float) >>> a.tolist() [1.0, 2.0, 3.0] >>> list(a) [1.0, 2.0, 3.0] >>> z = a.tolist() >>> z [0.0, 2.0, 3.0] >>> type(z) <class 'list'> >>> y = list(a) >>> y [0.0, 2.0, 3.0] >>> type(y) <class 'list'>
使用 tostring 方法可以把陣列內的原始資料轉換成二進制字串(不是人類可讀的格式)。fromstring 方法可以用這個二進制的數據建立陣列。這些方法對儲存大量數據到檔案來說很方便。
>>> a = array([1, 2, 3], float) >>> s = a.tostring() >>> s '\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00 \x00\x00\x08@' >>> np.fromstring(s) array([ 1., 2., 3.])
補充:
.tostring 方法即將被棄用,改名為 .tobytes() 用法及結果都是一樣的
fill 方法可以把陣列填入指定的值。
>>> a = array([1, 2, 3], float) >>> a array([ 1., 2., 3.]) >>> a.fill(0) >>> a array([ 0., 0., 0.])
陣列的 transpose 方法可以生成陣列的轉置陣列,會生成兩個維度對調的新陣列
>>> a = np.array(range(6), float).reshape((2, 3)) >>> a array([[ 0., 1., 2.], [ 3., 4., 5.]]) >>> a.transpose() array([[ 0., 3.], [ 1., 4.], [ 2., 5.]])
多維陣列可以使用 flatten()方法,產生新的一維陣列
>>> a = np.array([[1, 2, 3], [4, 5, 6]], float) >>> a array([[ 1., 2., 3.], [ 4., 5., 6.]]) >>> a.flatten() array([ 1., 2., 3., 4., 5., 6.])
兩個以上的陣列,可以使用 concatenate 函數,使用 tuple格式的參數將陣列聯集起來
>>> a = np.array([1,2], float) >>> b = np.array([3,4,5,6], float) >>> c = np.array([7,8,9], float) >>> np.concatenate((a, b, c)) array([1., 2., 3., 4., 5., 6., 7., 8., 9.])
如果陣列是多於一維陣列,可以透過指定維度來聯集多維陣列,如果沒有指定維度,NumPy 預設用第一個維度
>>> a = np.array([[1, 2], [3, 4]], float) >>> b = np.array([[5, 6], [7,8]], float) >>> np.concatenate((a,b)) array([[ 1., 2.], [ 3., 4.], [ 5., 6.], [ 7., 8.]]) >>> np.concatenate((a,b), axis=0) array([[ 1., 2.], [ 3., 4.], [ 5., 6.], [ 7., 8.]]) >>> np.concatenate((a,b), axis=1) array([[ 1., 2., 5., 6.], [ 3., 4., 7., 8.]])
陣列的維度可以用括號中的 newaxis 常數來增加維度
>>> a = np.array([1, 2, 3], float) >>> a array([1., 2., 3.]) >>> a[:,np.newaxis] array([[ 1.], [ 2.], [ 3.]]) >>> a[:,np.newaxis].shape (3,1) >>> b[np.newaxis,:] array([[ 1., 2., 3.]]) >>> b[np.newaxis,:].shape (1,3)
這裡的範例都是二維的,其中用 np.newaxis 建立的陣列,長度為1。使用 newxis 方式建立陣列,對於向量跟矩陣的數學計算來說很方便。