為什麼你就是學不會 Numpy ?

為什麼你就是學不會 Numpy ? | 技術頭條

作者 | Che_Hongshu

前言

玩數據分析、數據挖掘、AI的都知道這個Python庫用的是很多的,裡面包含各種操作,在實際的DataSet的處理當中是非常常用的,這裡我做一個總結,方便自己看,也方便大家看,我準備做一個非常細緻的分類,每個分類有對應的NumPy常用用法,以後見到或者用到再一個個慢慢加進來。

下載、安裝、導入

用Anaconda安裝是十分方便的,如果你已經安裝了tf、Keras之類的,其實已經直接把NumPy安裝了,一般來說安裝就是pip命令。

1pip install numpy #py2
2pip3 install numpy #py3
用法則是:
1import numpy as np # 一般as為np來操作

常用用法總結

1.Array基本信息以及生成各種常見Array基本操作 

生成Array,得到對應的基本信息:

1import numpy as np
2
3array = np.array([[1, 2, 3],
4 [2, 3, 4]])
5
6print array #numpy生成的array
7print array.dtype # 每個元素的類型
8print "number of dim", array.ndim # array的維度
9print 'shape:', array.shape #形狀, 兩行三列。
10print 'size:', array.size #array的大小=array中所有元素的個數
11"""
12 [[1 2 3]
13 [2 3 4]]
14 int64
15 number of dim 2
16 shape: (2, 3)
17 size: 6
18"""
Array的生成就是np.array(list),本質上是把定義的list轉換成Array,
因為Array可以進行更加方便地計算和操作,比如矩陣的轉置和相乘。

Array的dtype設置:

 1import numpy as np
2
3a = np.array([2, 23, 4], dtype=np.float32)
4print "a's dtype", a.dtype
5aa = np.array([2, 23, 4], dtype=np.int)
6print "aa's dtype", aa.dtype
7aaa = np.array([2, 23, 4])
8print "aaa's dtype", aaa.dtype
9aaaa = np.array([2.2, 23.2, 4.2])
10print "aaaa's dtype", aaaa.dtype
11aaaaa = np.array([2, 23, 4], dtype=np.int64)
12print "aaaaa's dtype:", aaaaa.dtype
13

14"""
15 a's dtype float32
16 aa's dtype int64
17 aaa's dtype int64
18 aaaa's dtype float64
19 aaaaa's dtype: int64
20"""
由可以得到一個結論就是如果定義的Array裡面的list的元素本身為整數的話,不設置type,則默認為INT64;如果設置為INT類型而沒有設置字節大小則還是默認為INT64,如果元素本身為小數,則默認為FLOAT64。
所以如果用INT64,則如果元素都為整數則不需要設置默認即可,設置其他類型需要設置,FLOAT類似。
生成常見Array格式:
1a1 = np.zeros((2, 3), dtype=np.int) # 生成shape=(2, 3)的全為0的array
2
3print a1
4"""
5 [[0 0 0]
6 [0 0 0]]
7"""
8
9a2 = np.ones((3, 4), dtype=np.int16) # 生成shape=(3, 4)的全為1的array
10
11print a2
12"""
13 [[1 1 1 1]
14 [1 1 1 1]
15 [1 1 1 1]]
16"""
這裡注意shape=(a,b),在填入shape的參數的時候一定要加括號,以下雷同。
1a3 = np.empty((3, 4)) # 生成shape=(3, 4)的全為接近空的array
2print a3
3"""
4 [[6.92259773e-310 4.67497449e-310 6.92259751e-310 6.92259750e-310]
5 [2.37151510e-322 3.16202013e-322 0.00000000e+000 6.92257087e-310]
6 [6.92259748e-310 6.92257087e-310 6.92257063e-310 6.92257063e-310]]

7"""
8a4 = np.arange(10, 20, 2)  # 生成array 10到20 每隔2的一增加,for循環中主要使用
9print a4
10"""
11 [10 12 14 16 18]
12"""
13
14a5 = np.arange(12) # 生成array 0到12-1=11 每一個增加,for循環中非常常用
15print a5
16"""
17 [ 0 1 2 3 4 5 6 7 8 9 10 11]
18"""
19
20a6 = np.arange(12).reshape((3,4)) # 這裡主要展示reshape的功能,能夠重新定義矩陣的形狀
21print a6
22"""
23 [[ 0 1 2 3]
24 [ 4 5 6 7]
25 [ 8 9 10 11]]
26"""
27 # 1和10之間4個元素越過,這個主要應用在插值運算或者matplotlib畫光滑曲線的時候計算用到。
28a7 = np.linspace(1, 10, 4).reshape((2, 2)) 
29
30print a7
31"""
32 [[ 1. 4.]
33 [ 7. 10.]]
34
35"""
2.Array之間的計算

加減法,相同維度:

 1import numpy as np
2
3a = np.array([10, 20, 30, 40])
4b = np.arange(4)

5print "a:", a
6print "b:", b
7c = a+b
8print "c:", c
9c1 = a-b
10print "c1:", c1
11"""
12 a: [10 20 30 40]
13 b: [0 1 2 3]
14 c: [10 21 32 43]
15 c1: [10 19 28 37]
16"""
不同維度:
1aa = np.array([[1, 2, 3, 4],
2 [11, 22, 33, 44]])
3
4bb = np.arange(4)
5
6print "aa:", aa
7print "bb:", bb
8print "a+b:", aa+bb
9
10"""
11 aa: [[ 1 2 3 4]
12 [11 22 33 44]]
13 bb: [0 1 2 3]
14 a+b: [[ 1 3 5 7]
15 [11 23 35 47]]
16"""

如果是不同維度的Array進行加減法的話,

程序就是把維度低的Array自動複製擴展到大維度的Array進行相加。

當然前提條件是兩個不同維度的Array進行相加的時候。

低維度的Array的shape也要和高維度的Array其中一個shape相同,例如上面代碼所示,(2,4) (1,4) 都有個shape為4。

乘除法:

 1d = np.array([[1, 2],
2 [3, 4]])
3e = np.arange(1, 8, 2).reshape((2, 2))
4print "d:", d
5print "e:", e
6
7print "d*e:", d*e #對應元素相乘
8print "d/e", d/e #對應元素相除,因為是int64類型所以類似於2/3=0
9"""
10 d: [[1 2]
11 [3 4]]
12 e: [[1 3]
13 [5 7]]
14 d*e: [[ 1 6]
15 [15 28]]
16 d/e [[1 0]
17 [0 0]]
18"""
不同緯度的乘除法和上面加減法解析情況一樣,可對比來看。

平方,三角函數,比較元素大小:

1a = np.array([10, 20, 30, 40])
2b = np.arange(4)
3c2 = b**2 # 平方
4print "c2:", c2
5
6c3 = 10*np.sin(a) # sin函數
7print "c3:", c3
8"""
9c2: [0 1 4 9]
10c3: [-5.44021111 9.12945251 -9.88031624 7.4511316 ]
11"""
12print "b:", b
13print "b:", b < 3 # b中小於3的都為TRUE
14print "b:", b == 3 # b中等於3的為TRUE

15"""
16b: [0 1 2 3]
17b: [ True True True False]
18b: [False False False True]
19
20"""
矩陣相乘:
1d = np.array([[1, 2],
2 [3, 4]])
3e = np.arange(1, 8, 2).reshape((2, 2))
4print "d:", d
5print "e:", e
6print np.dot(d, e)
7print d.dot(e)
8"""
9 d: [[1 2]
10 [3 4]]
11 e: [[1 3]
12 [5 7]]
13 [[11 17] #例如11 為1*1+2*5=11
14 [23 37]]
15 [[11 17]
16 [23 37]]
17
18"""
np.dot(d, e) 與d.dot(e)一樣,都為d和e進行矩陣相乘:隨機數和max、min、sum。
1f = np.random.random((2, 4)) #隨機產生shape為(2,4)的一個array,每個元素都為0-1之間隨機生成
2print f
3print "=------="
4print np.sum(f)
5print np.min(f)
6print np.max(f)
7"""
8[[0.11027523 0.84841991 0.59866992 0.92557867]
9 [0.99917522 0.2771565 0.25578198 0.06671013]]
10=------=
114.081767552987877
120.06671012832269874
130.9991752153886827
14"""
15print "============="
16print np.sum(f, axis=0)
17print np.min(f, axis=1)
18print np.max(f, axis=0)
19"""

20[1.10945044 1.12557641 0.8544519 0.9922888 ]
21[0.11027523 0.06671013]
22[0.99917522 0.84841991 0.59866992 0.92557867]
23"""

顧名思義,sum為總,min為最小,max為最大,如果不設置axis維度參數的話,則都為整個array的元素來說,但一般我們運用都只是算某個維度的sum、max、min,在二維數據中,axis=0代表行,第一個維度,axis=1,代表列為第二個維度,其實這麼記並不是很好很有可能記錯。

我一般都是這麼記的:axis=0為行,那意思就是每一行都要算唄?算完那不就是一列的每一行算個數被,axis=1類推,多維數據類推即可。

矩陣轉置和排序,以及元素比較大小重置元素方法:

 1c = np.arange(14, 2, -1).reshape((3, 4))
2
3print c
4print "sort:", np.sort(c)# 每一行進行重新大小排序當然也有axis參數配置,根據我的axis參數說明來操作
5
6print np.transpose(c) #轉置 同下面操作
7print c.T # 轉置 同上面操作
8
9print "clip:",np.clip(c, 5, 9)#c矩陣中的元素小於5的等於5,大於9的等於9
10"""
11 [[14 13 12 11]
12 [10 9 8 7]
13 [ 6 5 4 3]]
14 sort: [[11 12 13 14]

15 [ 7 8 9 10]
16 [ 3 4 5 6]]
17 [[14 10 6]
18 [13 9 5]
19 [12 8 4]
20 [11 7 3]]
21 [[14 10 6]
22 [13 9 5]
23 [12 8 4]
24 [11 7 3]]
25 clip: [[9 9 9 9]
26 [9 9 8 7]
27 [6 5 5 5]]
28"""
平均值、中值,累加,後減前:
1a = np.arange(2, 14).reshape((3, 4))
2print "a:", a
3print "average:", np.average(a) #平均值
4print "median:", np.median(a) #中值
5
6print "cumsum:", np.cumsum(a) #每個元素變成當前元素+前面所有元素的和
7print "diff:", np.diff(a) #當前元素減去前面元素的差
8"""
9 a: [[ 2 3 4 5]
10 [ 6 7 8 9]
11 [10 11 12 13]]
12 average: 7.5
13 median: 7.5
14 cumsum: [ 2 5 9 14 20 27 35 44 54 65 77 90]
15 diff: [[1 1 1]
16 [1 1 1]
17 [1 1 1]]
18"""

3.索引

最大值最小值索引,非零索引:

 1a = np.array([[2, 6, 0, 4],
2 [4, 8, 9, 1],
3 [10, 2, 3, 11]])

4print "argmin:", np.argmin(a)
5print "axis0:", np.argmin(a, axis=0)
6print "axis1:", np.argmin(a, axis=1)
7print "argmax:", np.argmax(a)
8print "zero:", np.nonzero(a)
9
10"""
11argmin: 2
12axis0: [0 2 0 1]
13axis1: [2 3 1]
14argmax: 11
15zero: (array([0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2]), array([0, 1, 3, 0, 1, 2, 3, 0, 1, 2, 3]))
16"""

argmin/argmax都是返回最小值/最大值的索引的函數。

這裡的axis和上面的分析是完全一致的,例如argmin(a)就是最小的索引,雖小的毋庸置疑是0,所以總體來講從第一行第一個元素到最後一行最後一個元素。

總體來算索引,那就是第二個為0,所以返回2,如果axis=0說明一列中的每一行來比較,那第一列比較出來最小的為2,即索引為0,因為每一列的每一行來比較所以最後的維度為列數,在這裡即為4,以此列推。

非零索引的意思為非零的數返回索引,如上例為返回兩個Array,前面Array對應行索引,後面對應列索引,一前一後加一起的shape才對應一個非零索引

取值,取列或行:

 1import numpy as np
2
3a = np.arange(3, 15).reshape((3, 4))
4
5print a
6print a[1] #索引為1的行,同下
7print a[:][1] #索引為1的行,同上
8print "=========-------==========="
9print a[2][1] #和數組一樣的表示
10print a[2, 1] #同上,這才是比較標準的array的索引表示,前面是行後面是列的索引
11print "=========---------============"
12print a[:, 1]   #索引為1的列,生成為行向量
13print a[:, 1:2]  #索引為1的列,生成為列向量
14print a[:, 1:3]  
15
16print a[1, 1:3] #為上面a[:, 1:3]的索引為1的行向量
17"""
18 [[ 3 4 5 6]
19 [ 7 8 9 10]
20 [11 12 13 14]]
21 [ 7 8 9 10]
22 [ 7 8 9 10]
23 =========-------===========
24 12
25 12
26 =========---------============
27 [ 4 8 12]
28 [[ 4]
29 [ 8]
30 [12]]
31 [[ 4 5]
32 [ 8 9]
33 [12 13]]
34 [8 9]
35"""

著重講一下 a[:, 1:2] a[:, 1:3] a[1, 1:3]:

a[:, 1:2]::代表行所有也就是一列要的話,這一列的每一行都要,1:2對應的從索引為1的列來算移植相當於取到索引為(2-1)的列,2為取的最高索引大一個。

所以總體來講就是首先取每一行,之後在行裡取索引1->1的列元素,所以為最終的結果列向量。

a[:, 1:3]:按照上面的分析則每一行都要,列要索引為1和(3-1)的元素,那就是索引為1和2的所有元素,也就是第二列和第三列的元素。

a[1, 1:3]:為a[:, 1:3]的索引為1的所有元素。

這裡需要注意的是:a[:, 1] #索引為1的列,生成為行向量,a[:, 1:2] #索引為1的列,生成為列向量。

因為兩種取值的思想不一樣,最終造成的結果也不一樣,一個是直接取,所以維度減少了一個,另一個是在原本維度上截取,最終還是原來的維度。

迭代元素和降維:

 1a = np.arange(3, 15).reshape((3, 4))# 數據都是下取上差一個取到。
2print a
3print "row"
4for row in a: #取每一行迭代
5 print row

6print "column"
7for column in a.T: #每一列迭代
8 print column
9print "====================="
10print a.flatten() # 所有元素變成一維
11b = np.array([[1, 2, 3]]) 
12print b
13print b.flatten() #降維
14
15for item in a.flat: #每個元素打印
16 print item
17
18"""
19 [[ 3 4 5 6]
20 [ 7 8 9 10]
21 [11 12 13 14]]
22 row
23 [3 4 5 6]
24 [ 7 8 9 10]
25 [11 12 13 14]
26 column
27 [ 3 7 11]
28 [ 4 8 12]
29 [ 5 9 13]
30 [ 6 10 14]
31 =====================
32 [ 3 4 5 6 7 8 9 10 11 12 13 14]
33 [[1 2 3]]
34 [1 2 3]
35 3
36 4
37 5
38 6
39 7
40 8
41 9
42 10
43 11
44 12
45 13
46 14
47"""

行迭代,就是可以理解為最外層的維度進行迭代,列迭代就是利用轉置來完成。

flatten()函數的意思為把Array的內層的維度進行降一維,將內層的維度弄掉,則二維數據就成為一維數據了

4.合併與分開

兩個合併、多個合併(行向量轉換成列向量):

 1# -*- coding: utf-8 -*-
2import numpy as np
3
4a = np.array([1, 1, 2])
5b = np.array([2, 3, 4])
6
7c = np.vstack((a, b)) #vertical
8
9print "a:", a
10print "b:", b
11print "c:", c
12print "a,c shape:", a.shape, c.shape
13
14d = np.hstack((a, b)) #horizontal
15print "d:", d
16print d.shape
17"""
18 a: [1 1 2]
19 b: [2 3 4]
20 c: [[1 1 2]
21 [2 3 4]]
22 a,c shape: (3,) (2, 3)
23 d: [1 1 2 2 3 4]
24 (6,)
25"""
26print a.T # not transponse 行向量無法直接用轉置來變成列向量
27# 行向量變成列向量
28print a[np.newaxis, :].shape
29print a[:, np.newaxis].shape
30print a[:, np.newaxis] #轉換方法
31"""
32 [1 1 2]

33 (1, 3)
34 (3, 1)
35 [[1]
36 [1]
37 [2]]
38"""
39a = np.array([1, 1, 2])[:, np.newaxis]
40b = np.array([2, 3, 4])[:, np.newaxis]
41
42c = np.concatenate((a, b, b), axis=0) #多向量融合
43
44print c
45
46c = np.concatenate((a, b, b), axis=1) #多向量融合
47
48print c
49
50"""
51 [[1]
52 [1]
53 [2]
54 [2]
55 [3]
56 [4]
57 [2]
58 [3]
59 [4]]
60 [[1 2 2]
61 [1 3 3]
62 [2 4 4]]
63"""
分開:
1# -*- coding: utf-8 -*-
2import numpy as np
3
4a = np.arange(12).reshape((3, 4))
5
6print a
7print "平等分開"
8print "vertical:", np.split(a, 2, axis=1) #
9
10print "horizontal:", np.split(a, 3, axis=0) #
11"""
12 [[ 0 1 2 3]
13 [ 4 5 6 7]
14 [ 8 9 10 11]]
15 平等分開
16 vertical: [array([[0, 1],

17 [4, 5],
18 [8, 9]]), array([[ 2, 3],
19 [ 6, 7],
20 [10, 11]])]
21 horizontal: [array([[0, 1, 2, 3]]), array([[4, 5, 6, 7]]), array([[ 8, 9, 10, 11]])]
22"""
23print "不平等分開"
24print np.array_split(a, 3, axis=1)
25
26print "代替需要axis參數"
27print "vertical_a:", np.vsplit(a, 3)
28
29print "horizontal_a:", np.hsplit(a, 2)
30"""
31 不平等分開
32 [array([[0, 1],
33 [4, 5],
34 [8, 9]]), array([[ 2],
35 [ 6],
36 [10]]), array([[ 3],
37 [ 7],
38 [11]])]
39 代替需要axis參數
40 vertical_a: [array([[0, 1, 2, 3]]), array([[4, 5, 6, 7]]), array([[ 8, 9, 10, 11]])]
41 horizontal_a: [array([[0, 1],
42 [4, 5],
43 [8, 9]]), array([[ 2, 3],
44 [ 6, 7],
45 [10, 11]])]
46"""

5.元素傳遞和copy

Array這個元素傳遞有點意思的,就是如果直接a=b,其實從內存角度來考慮就相當於a和b指向了一樣的元素內存空間,所以改變一個元素的值,另一個一樣改變,如果想各是各的,並且還想傳遞另一個元素的值那就用a=b.copy(),所以這個還是需要注意的。

6.補充部分

array.min/max/ptp

 1import numpy as np
2
3a = [[2, 4, 8, 9], [1, 7, 4, 5], [5, 7, 1, 4]]
4a = np.array(a)
5print(a)
6print(a.min(0))
7print(a.min(1))
8print(a.ptp(0))
9"""
10[[2 4 8 9]
11 [1 7 4 5]
12 [5 7 1 4]]
13axis=0 為每列的最小值返回
14[1 4 1 4]
15axis=1 為每行的最小值返回
16[2 1 1]
17ptp為最大值減最小值的range
18[4 3 7 5]
19"""

np.random.choice:

1import numpy as np
2
3a = np.random.choice(a=100, size=20)
4print(a)
5"""
60-99之間選size為20的隨機數的list
7[78 82 91 96 5 60 28 79 24 56 5 34 58 48 96 57 77 23 80 69]
8"""

作者簡介:Che_Hongshu,CSDN 博客專家。碩士就讀於東南大學模式識別專業,方向為機器學習和序列分析部分。個人公眾號AI蝸牛車,致力於系統化一步步AI學習、數據分析庫、機器學習理論與實戰,深度學習理論與實戰應有盡有。


分享到:


相關文章: