前兩篇文章對NumPy數組做了基本的介紹,本篇文章對NumPy數組進行較深入的探討。首先介紹自定義類型的數組,接著數組的組合,最后介紹數組復制方面的問題。
自定義結構數組
通過NumPy也可以定義像C語言那樣的結構類型。在NumPy中定義結構的方法如下:
定義結構類型名稱;定義字段名稱,標明字段數據類型。
1
|
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 |
在定義好結構類型之后,就可以定義以該類型為元素的數組了:
1
|
a = array([(“Zhang”, 32 , 65.5 ), (“Wang”, 24 , 55.2 )], dtype = student) |
除了在每個元素中依次列出對應字段的數據外,還需要在array函數中最后一個參數指定其所對應的數據類型。
注:例子來源于張若愚的Python科學計算藝術的29頁。更多關于dtype的內容請參考《NumPy for Beginner》一書的第二章。
組合函數
這里介紹以不同的方式組合函數。首先創建兩個數組:
1
2
3
4
5
6
7
8
9
10
|
>>> 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 ]]) |
水平組合
1
2
3
4
|
>>> hstack((a, b)) array([[ 0 , 1 , 2 , 0 , 2 , 4 ], [ 3 , 4 , 5 , 6 , 8 , 10 ], [ 6 , 7 , 8 , 12 , 14 , 16 ]]) |
也可通過concatenate函數并指定相應的軸來獲得這一效果:
1
2
3
4
|
>>> concatenate((a, b), axis = 1 ) array([[ 0 , 1 , 2 , 0 , 2 , 4 ], [ 3 , 4 , 5 , 6 , 8 , 10 ], [ 6 , 7 , 8 , 12 , 14 , 16 ]]) |
垂直組合
1
2
3
4
5
6
7
|
>>> vstack((a, b)) array([[ 0 , 1 , 2 ], [ 3 , 4 , 5 ], [ 6 , 7 , 8 ], [ 0 , 2 , 4 ], [ 6 , 8 , 10 ], [ 12 , 14 , 16 ]]) |
同樣,可通過concatenate函數,并指定相應的軸來獲得這一效果。
1
2
3
4
5
6
7
|
>>> 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。顧名思義,就是在數組的第三個軸(即深度)上組合。如下:
1
2
3
4
5
6
7
8
9
10
11
12
|
>>> dstack((a, b)) array([[[ 0 , 0 ], [ 1 , 2 ], [ 2 , 4 ]], [[ 3 , 6 ], [ 4 , 8 ], [ 5 , 10 ]], [[ 6 , 12 ], [ 7 , 14 ], [ 8 , 16 ]]]) |
仔細觀察,發現對應的元素都組合成一個新的列表,該列表作為新的數組的元素。
行組合
行組合可將多個一維數組作為新數組的每一行進行組合:
1
2
3
4
5
6
7
8
9
|
>>> one = arange( 2 ) >>> one array([ 0 , 1 ]) >>> two = one + 2 >>> two array([ 2 , 3 ]) >>> row_stack((one, two)) array([[ 0 , 1 ], [ 2 , 3 ]]) |
對于2維數組,其作用就像垂直組合一樣。
列組合
列組合的效果應該很清楚了。如下:
1
2
3
|
>>> column_stack((oned, twiceoned)) array([[ 0 , 2 ], [ 1 , 3 ]]) |
對于2維數組,其作用就像水平組合一樣。
分割數組
在NumPy中,分割數組的函數有hsplit、vsplit、dsplit和split。可將數組分割成相同大小的子數組,或指定原數組分割的位置。
水平分割
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
>>> 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來獲得這樣的效果:
1
|
split(a, 3 , axis = 1 ) |
垂直分割
垂直分割是沿著垂直的軸切分數組:
1
2
|
>>> vsplit(a, 3 ) >>> [array([[ 0 , 1 , 2 ]]), array([[ 3 , 4 , 5 ]]), array([[ 6 , 7 , 8 ]])] |
同樣,也可通過solit函數并指定軸為1來獲得這樣的效果:
1
|
>>> split(a, 3 , axis = 0 ) |
面向深度的分割
dsplit函數使用的是面向深度的分割方式:
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
>>> 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)
當運算和處理數組時,它們的數據有時被拷貝到新的數組有時不是。這通常是新手的困惑之源。這有三種情況:
完全不復制
簡單的賦值,而不復制數組對象或它們的數據。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
>>> 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)和淺復制
不同的數組對象分享同一個數據。視圖方法創造一個新的數組對象指向同一數據。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
>>> 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 ]]) |
切片數組返回它的一個視圖:
1
2
3
4
5
6
|
>>> 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 ]]) |
深復制
這個復制方法完全復制數組和它的數據。
1
2
3
4
5
6
7
8
9
10
|
>>> 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 ]]) |
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:http://blog.csdn.net/sunny2038/article/details/8907736