前兩篇文章對NumPy陣列做了基本的介紹,本篇文章對NumPy陣列進行較深入的探討。首先介紹自訂類型的數組,接著數組的組合,最後介紹數組複製方面的問題。
自訂結構陣列
透過NumPy也可以定義像C語言那樣的結構型別。在NumPy中定義結構的方法如下:
定義結構類型名稱;定義欄位名稱,標示欄位資料類型。
student= dtype({'names':['name', 'age', 'weight'], 'formats':['S32', 'i','f']}, align = True)
這裡student是自訂結構類型的名稱,使用dtype函數創建,在第一個參數中,'names'和'formats '不能改變,names中列出的是結構中欄位名稱,formats中列出的是對應欄位的資料類型。 S32表示32位元組長度的字串,i表示32位元的整數,f表示32位元長度的浮點數。最後一個參數為True時,表示要求進行記憶體對齊。
欄位中使用NumPy的字元編碼來表示資料類型。更詳細的資料類型請參閱下表。
資料類型 | 字元編碼 |
整數 | i |
無符號整數 | u |
#單一精確度浮點數 | f |
雙精確度浮點數 | d |
#布林值 | b |
#複數 | D |
字串 | S |
Unicode | U |
Void | V |
#在定義好結構型別之後,就可以定義以此型別為元素的陣列了:
a= array([(“Zhang”, 32, 65.5), (“Wang”, 24, 55.2)], dtype =student)
除了在每個元素中依序列出對應欄位的資料外,還需要在array函數中最後一個參數指定其所對應的資料類型。
組合函數
這裡介紹以不同的方式組合函數。首先建立兩個陣列:
>>> a = arange(9).reshape(3,3) >>> a array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]) >>> b = 2 * a >>> b array([[ 0, 2, 4], [ 6, 8, 10], [12, 14, 16]])
#水平組合
>>> hstack((a, b)) array([[ 0, 1, 2, 0, 2, 4], [ 3, 4, 5, 6, 8, 10], [ 6, 7, 8, 12, 14, 16]])
也可透過concatenate函數並指定對應的軸來獲得此效果:
>>> concatenate((a, b), axis=1) array([[ 0, 1, 2, 0, 2, 4], [ 3, 4, 5, 6, 8, 10], [ 6, 7, 8, 12, 14, 16]])
垂直組合
>>> vstack((a, b)) array([[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8], [ 0, 2, 4], [ 6, 8, 10], [12, 14, 16]])
同樣,可透過concatenate函數,並指定對應的軸來獲得此效果。
>>> concatenate((a, b), axis=0) array([[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8], [ 0, 2, 4], [ 6, 8, 10], [12, 14, 16]])
深度組合
另外,還有深度方面的組合函數dstack。顧名思義,就是在陣列的第三個軸(即深度)上組合。如下:
>>> dstack((a, b)) array([[[ 0, 0], [ 1, 2], [ 2, 4]], [[ 3, 6], [ 4, 8], [ 5, 10]], [[ 6, 12], [ 7, 14], [ 8, 16]]])
仔細觀察,發現對應的元素都組合成一個新的列表,該列表作為新的數組的元素。
行組合
#行組合可將多個一維陣列作為新陣列的每一行組合:
>>> one = arange(2) >>> one array([0, 1]) >>> two = one + 2 >>> two array([2, 3]) >>> row_stack((one, two)) array([[0, 1], [2, 3]])
對於2維數組,其作用就像垂直組合一樣。
列組合
列組合的效果應該很清楚了。如下:
>>> column_stack((oned, twiceoned)) array([[0, 2], [1, 3]])
對於2維數組,其作用就像水平組合一樣。
分割陣列
在NumPy中,分割陣列的函式有hsplit、vsplit、dsplit和split。可將陣列分割成相同大小的子數組,或指定原數組分割的位置。
水平分割
>>> a = arange(9).reshape(3,3) >>> a array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]) >>> hsplit(a, 3) [array([[0], [3], [6]]), array([[1], [4], [7]]), array([[2], [5], [8]])]
也呼叫split函數並指定軸為1來得到這樣的效果:
split(a, 3, axis=1)
垂直分割
垂直分割是沿著垂直的軸切分陣列:
>>> vsplit(a, 3) >>> [array([[0, 1, 2]]), array([[3, 4, 5]]), array([[6, 7, 8]])]
同樣,也可透過solit函數並指定軸為1來得到這樣的效果:
>>> split(a, 3, axis=0)
面向深度的分割
#dsplit函數使用的是面向深度的分割方式:
>>> c = arange(27).reshape(3, 3, 3) >>> c array([[[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8]], [[ 9, 10, 11], [12, 13, 14], [15, 16, 17]], [[18, 19, 20], [21, 22, 23], [24, 25, 26]]]) >>> dsplit(c, 3) [array([[[ 0], [ 3], [ 6]], [[ 9], [12], [15]], [[18], [21], [24]]]), array([[[ 1], [ 4], [ 7]], [[10], [13], [16]], [[19], [22], [25]]]), array([[[ 2], [ 5], [ 8]], [[11], [14], [17]], [[20], [23], [26]]])]
複製和鏡像(View)
當運算和處理陣列時,它們的資料有時會被拷貝到新的數組有時不是。這通常是新手的困惑之源。這有三種情況:
完全不複製
簡單的賦值,而不複製陣列物件或它們的資料。
>>> a = arange(12) >>> b = a #不创建新对象 >>> b is a # a和b是同一个数组对象的两个名字 True >>> b.shape = 3,4 #也改变了a的形状 >>> a.shape (3, 4) Python 传递不定对象作为参考4,所以函数调用不拷贝数组。 >>> def f(x): ... print id(x) ... >>> id(a) #id是一个对象的唯一标识 148293216 >>> f(a) 148293216
視圖(view)和淺複製
不同的陣列物件分享同一個數據。視圖方法創造一個新的陣列物件指向相同資料。
>>> c = a.view() >>> c is a False >>> c.base is a #c是a持有数据的镜像 True >>> c.flags.owndata False >>> >>> c.shape = 2,6 # a的形状没变 >>> a.shape (3, 4) >>> c[0,4] = 1234 #a的数据改变了 >>> a array([[ 0, 1, 2, 3], [1234, 5, 6, 7], [ 8, 9, 10, 11]])
#切片陣列傳回它的一個檢視:
>>> s = a[ : , 1:3] # 获得每一行1,2处的元素 >>> s[:] = 10 # s[:] 是s的镜像。注意区别s=10 and s[:]=10 >>> a array([[ 0, 10, 10, 3], [1234, 10, 10, 7], [ 8, 10, 10, 11]])
深複製
這個複製方法完全複製陣列和它的資料。
>>> d = a.copy() #创建了一个含有新数据的新数组对象 >>> d is a False >>> d.base is a #d和a现在没有任何关系 False >>> d[0,0] = 9999 >>> a array([[ 0, 10, 10, 3], [1234, 10, 10, 7], [ 8, 10, 10, 11]])
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持PHP中文網。
更多深入理解NumPy簡明教學---陣列3(組合)相關文章請關注PHP中文網!