本文實例講述了Python Numpy庫常見用法。分享給大家供大家參考,具體如下:
1、簡介
Numpy是一個常用的Python科學技術庫,通過它可以快速對數組進行操作,包括形狀操作、排序、選擇、輸入輸出、離散傅立葉變換、基本線性代數,基本統計運算和隨機模擬等。許多Python庫和科學計算的軟件包都使用Numpy數組作為操作對象,或者將傳入的Python數組轉化為Numpy數組,因此在Python中操作數據離不開Numpy。
Numpy的核心是ndarray對象,由Python的n維數組封裝而來,但通過C語言預編譯相關的數組操作,因此比原生Python具有更高的執行效率,但仍然使用Python語言編碼,這樣就同時具有簡潔的代碼和高效的運行速度。ndarry與數組有些區別值得注意,numpy數組中的元素都具有相同的類型,并且在創建時就確定了固定的大小,這與Python數組對象可以動態增長不同。
2、數組對象
2.1、屬性
Numpy對象的形式是同構多維數組,數組的維度稱為軸(axis),每個維度上元素的個數稱為軸的長度。例如下面是一個2×3的二維數組arr,第一軸長度為3,第二軸長度為2
1
2
|
arr = [[ 1. , 0. , 0. ], [ 0. , 1. , 2. ]] |
arr數組對象常用的屬性如下:
1
2
3
4
5
6
7
8
9
10
|
# 數組軸的個數 arr.ndim # 數組維度及長度,例如2×3的數組其shape為(2, 3) arr.shape # 數組元素的總個數 arr.size # 數組中元素的數據類型 arr.dtype # 數組中元素所占字節數 arr.itemsize |
2.2、創建數組
可以通過array()方法包裹普通python數組將其轉化為numpy數組,通過dtype=規定元素的數據類型。數組可以是二維等高維數組,也可以是元組的形式。
如果需要填充已知大小的數組可以使用函數zeros(),將元素都填充為0,或者ones()將元素填充為1,empty()將元素填充為隨機數
arange(a,b,c)函數用于從a到b每隔c長度生成一個數組元素。linspace(a,b,c)函數用于在a到b之間生成c個數組元素
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
|
# 普通數組轉化為numpy數組 a1 = np.array([ 2 , 3 , 4 ], dtype = float ) print (a1) # 將元組數組轉化為二維numpy數組 a2 = np.array([( 1 , 2 , 3 ), ( 3 , 4 , 5 )]) print (a2) # 將3×3的數組用1填充 a3 = np.ones(( 3 , 3 )) print (a3) # 從1到10,每隔2生成一個元素 a4 = np.arange( 1 , 10 , 2 ) print (a4) # 在1到12之間生成4個元素 a5 = np.linspace( 1 , 12 , 4 , dtype = int ) print (a5) ''' 普通數組轉化為numpy對象: [2. 3. 4.] 元組數組: [[1 2 3] [3 4 5]] 用1填充數組: [[1. 1. 1.] [1. 1. 1.] [1. 1. 1.]] 從1到10每隔2生成一個元素: [1 3 5 7 9] 在1到12之間生成4個元素: [ 1 4 8 12] ''' |
2.3、數組操作
算術運算符可以直接運用在矩陣上,其結果是將運算應用到每個元素上,例如矩陣A*B就是每個元素對應相乘,矩陣的乘法運算使用的是@符號
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
A = np.array([[ 1 , 1 ], [ 0 , 1 ]]) B = np.array([[ 2 , 0 ], [ 3 , 4 ]]) print (A * B) print (A @ B) ''' 矩陣元素對應相乘: [[2 0] [0 4]] 矩陣的乘法: [[5 4] [3 4]] ''' |
numpy中有些函數應用于整個數組,例如求和sum、最大值max、最小值min。如果在這些參數中指定了某個軸,則應用于指定軸。
還有一些函數應用于數組中的具體元素,例如求sin、cos、exp、開方sqrt等,這些函數叫做通函數(ufunc)
1
2
3
4
5
6
|
a = np.array([[ 0 , 1 , 2 , 3 ], [ 4 , 5 , 6 , 7 ], [ 8 , 9 , 10 , 11 ]]) print (a. max ()) # 求整體的最大值,結果為11 print (a. sum (axis = 0 )) # 求每一列的和,結果為:[12 15 18 21] print (np.sqrt(a)) # 數組每個元素求開方 |
numpy中的數組同python中的list一樣可以進行索引、切片和迭代操作。數組a[x]代表訪問數組a下標為x的元素,一維數組a[x:y]代表訪問數組從x到y的元素,如果省略x代表從頭開始,省略y代表直到結尾。a[x:y:a]代表從x到y每隔a個元素取一個值,如果a為負數,代表逆序取值。
1
2
3
|
a = np.array([ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ]) print (a[ 1 : 3 ]) # 輸出下標為1到3的元素:[1 2] print (a[:: - 2 ]) # 逆序每隔兩個元素選一個值:[9 7 5 3 1] |
如果是多維數組,則索引之間用逗號分隔。可以使用...代表省略某幾個維度,如果省略則會被認為是該維度全部輸出,例如x[...,3]
等效于 x[:,:,:,:,3]
。
可以通過for循環迭代多為數組,其內容為低一維度的子數組,如果希望遍歷每一個子元素,可以使用flat屬性。
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
|
a = np.array([[ 0 , 1 , 2 , 3 ], [ 10 , 11 , 12 , 13 ], [ 40 , 41 , 42 , 43 ]]) # 輸出a第一維(行)的前三個,第二維(列)下標的1~3 print (a[ 1 : 3 , 0 : 3 ]) # 輸出行的所有,下標為2的列 print (a[ 2 , ...]) # 遍歷數組 for row in a: print (row) # 遍歷每個子元素 for item in a.flat: print (item) ''' 后兩行的1~3列: [[10 11 12] [40 41 42]] 第三行的所有列: [40 41 42 43] 遍歷數組: [0 1 2 3] [10 11 12 13] [40 41 42 43] 遍歷每個元素: 0 1 2 ...... 41 42 43 ''' |
除了使用具體數字作為索引,還可以使用numpy數組作為索引。例如使用數組i作為一維數組a的索引,輸出a[i]。當數組i為多維數組時,從a中選出元素填到i數組的對應位置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
a = np.arange( 12 ) * * 2 print (a) i = np.array([ 1 , 3 , 5 ]) print (a[i]) # 多維數組索引j j = np.array([[ 3 , 4 ], [ 9 , 7 ]]) print (a[j]) ''' [ 0 1 4 9 16 25 36 49 64 81 100 121] 數組a的1、3、5個元素 [ 1 9 25] 通過多為索引j取出a的數據填到對應位置 [[ 9 16] [81 49]] ''' |
如果a是多維數組,索引數組的單個元素代表選中數組a的第一個維度
如果對多維數組在多個維度上進行索引,則傳入多個索引數組i,j并用逗號分隔
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
a = np.array(([[ 0 , 1 , 2 , 3 ], [ 4 , 5 , 6 , 7 ], [ 8 , 9 , 10 , 11 ]])) # 多維數組的單元素索引 i = np.array([ 0 , 1 ]) print (a[i]) # 對多維數組提供多維度索引,同時提供i,j代表取出a的[0,2]、[1,3]兩個元素 j = np.array([ 2 , 3 ]) print (a[i, j]) ''' 選擇多維數組a的第0、1兩行: [[0 1 2 3] [4 5 6 7]] a的[0,2]、[1,3]兩個元素: [2 7] ''' |
2.4、改變維度
數組的reshape()方法可以將原數組重構成目標維度的數組,例如將一個2×6的數組重構為3×4的數組,
數組在重構時不會修改原數組,而是返回修改后的結果數組
值得注意的是數組在重構和打印時都是從最右邊的維度開始往左進行,例如下面的3×4的數組b,先按行排列4個,然后再換行,排列這樣的3行。如果是多維,則按這樣的行列繼續輸出。如果數組維度為-1,則會自動計算該維度的大小,例如含有12個元素的數組,第二、第三維是3×2,則第一維就是2
ravel()函數可以將數組展成一維數組。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
a = np.array([[ 1 , 2 , 3 , 4 , 5 , 6 ], [ 7 , 8 , 9 , 10 , 11 , 12 ]]) b = a.reshape( 3 , 4 ) print (b) # 多維數組,自動計算 print (a.reshape( - 1 , 3 , 2 )) # 展開數組 flatted = b.ravel() print (flatted, end = ' ' ) ''' [[ 1 2 3 4] [ 5 6 7 8] [ 9 10 11 12]] 2×3×2的多維數組: [[[ 1 2] [ 3 4] [ 5 6]] [[ 7 8] [ 9 10] [11 12]]] 展開數組: [ 1 2 3 4 5 6 7 8 9 10 11 12] ''' |
numpy的hstack()函數可以在水平方向上合并多個數組,vstack()函數可以在垂直方向上合并多個數組
相反地,hsplit()、vsplit()可以拆分為指定數量的數組
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
a = np.array([ 1 , 2 , 3 ]) b = np.array([ 4 , 5 , 6 ]) # 垂直方向合并 c = np.vstack((a,b)) print (c) # 水平方向合并 print (np.hstack((a,b))) # 水平方向拆分 print (np.hsplit(c, 3 )) ''' 垂直堆疊 [[1 2 3] [4 5 6]] 水平合并 [1 2 3 4 5 6] 水平拆分為三個1×2的: [array([[1], [4]]), array([[2], [5]]), array([[3], [6]])] ''' |
2.5、數組的復制
當一個數組對象賦值給一個新的變量時,是新開辟一個存儲空間還是只是傳遞一個引用?答案是引用。
例如執行語句b=a,只是將一個引用傳給了b,對b執行的操作會直接影響a。查看a、b兩個對象的節點id也是一樣的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
a = np.array([ 1 , 2 , 3 ]) b = a # 修改b b[ 0 ] = 0 print (a) # 輸出a、b對象的id print ( id (a), id (b)) ''' 修改b,a也發生了變化 [0 2 3] 查看二者的id 2290013812656 2290013812656 ''' |
通過切片返回數組的視圖,修改視圖的形狀不會影響原數組,但是在視圖上修改數據原數組也會改變。在執行del a之后,由于c引用了a,a依舊會存在內存中不會被刪除
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
c = a[:] # 修改視圖的形狀 c.shape = 3 , 1 print (c, a) # 修改視圖c的數據 c[ 0 ] = 1 print (a[ 0 ]) ''' 對視圖c的形狀做修改,a不會受到影響 [[ 0 ] [ 2 ] [ 3 ]] [ 0 2 3 ] 修改c的數據,a也會隨之改變: 1 |
通過copy()方法可以生成數據的副本,因此對副本的操作完全不會影響原數組
1
2
3
4
|
d = a.copy() d[ 0 ] = 5 # 修改數組的副本d,a不受影響,輸出a:[1 2 3] print (a) |
希望本文所述對大家Python程序設計有所幫助。
原文鏈接:https://blog.csdn.net/theVicTory/article/details/103011188