1. 程式人生 > 實用技巧 >應上一篇的評論,寫一下thingsboard打包成功以後,後續安裝使用

應上一篇的評論,寫一下thingsboard打包成功以後,後續安裝使用

認識NumPy

NumPy是Python的一個科學計算庫,用於快速處理大型矩陣,可以看做是開啟人工智慧的一把鑰匙。

在Python中本身提供的有list結構,但是list中的元素可以是任何物件,就會導致list中儲存的是物件的指標,進行運算的時候就得去做記憶體定址,型別檢測等事情,顯然會浪費比較多的記憶體和CPU資源。在大資料的環境下,list結構難以勝任。

NumPy的很多底層函式都是用C語言編寫,所以執行速度是普通Python程式碼無法相比的。

注:NumPy中的陣列型別名叫anarray,在本文中一般直接稱作矩陣或陣列。

安裝

pip3 install numpy

import numpy as np
print(np.__version__)

列印結果:

1.19.2

注:匯入的numpy模組一般都會命名為np,因此在本文中只要出現np.xxx 指的都是numpy模組中的xxx函式或屬性。

建立矩陣

基本建立

轉化生成

建立矩陣使用np.array方法進行建立,可傳入列表、元組、字典,將傳入的物件轉化為矩陣。

也可以指定儲存的資料型別dtype,不指定dtype的話預設會自動判斷型別。dtype一般有有符號整數int8、int16、int32,無符號整數unit8、unit16、unit32、浮點數float16、float32、float64,布林值bool,複數complex、complex64、complex128。

list1 = [0,1,2,3,4]
arr1 = np.array(list1)
print(arr1)
print(f'矩陣的物件型別:{type(arr1)}')
print(f'矩陣的資料型別:{arr1.dtype}')
print(f'矩陣的元素總數:{arr1.size}')
print(f'矩陣的維數:{arr1.ndim}')
print(f'矩陣的形狀:{arr1.shape}')

列印結果:

[0 1 2 3 4]
矩陣的物件型別:<class 'numpy.ndarray'>
矩陣的資料型別:int32
矩陣的元素總數:5
矩陣的維數:1
矩陣的形狀:(5,)
列印的形狀代表這是有5個元素的一維矩陣。

list2 = [[0,1,2,3,4],[5,6,7,8,9]]
arr2 = np.array(list2)
print(arr2)
print(f'矩陣的物件型別:{type(arr2)}')
print(f'矩陣的資料型別:{arr2.dtype}')
print(f'矩陣的元素總數:{arr2.size}')
print(f'矩陣的維數:{arr2.ndim}')
print(f'矩陣的形狀:{arr2.shape}')

列印結果:

[[0 1 2 3 4]
[5 6 7 8 9]]
矩陣的物件型別:<class 'numpy.ndarray'>
矩陣的資料型別:int32
矩陣的元素總數:10
矩陣的維數:2
矩陣的形狀:(2, 5)

列印的形狀代表這是一個2行5列的矩陣。

指定儲存的資料型別可以傳入dtype引數:np.array([2,3,4],dtype=np.int64)

建立連續值的矩陣

與Python的range函式相同,NumPy也提供了arange函式,用來建立連續值的矩陣,但是是一維矩陣。

np.arange([start,] stop[, step,], dtype=None)

如果start和stop都指定,那麼生成的值為左閉右開區間

arr = np.arange(0,10)
print(arr)

列印結果:

[0 1 2 3 4 5 6 7 8 9]

如果只指定一個引數,那麼即為stop,預設start為0

arr = np.arange(10)
print(arr)

列印結果:

[0 1 2 3 4 5 6 7 8 9]

如果傳入三個引數,那麼第三個為步長

arr = np.arange(0,10,2)
print(arr)

列印結果:

[0 2 4 6 8]

如果不想傳入start也要指定步長

arr = np.arange(10,step=2)
print(arr)

列印結果:

[0 2 4 6 8]

等差數列與等比數列

等差數列:np.linspace(start,stop,num=50,endpoint=True,retstep=False,dtype=None)

start:起始值
stop:結束值
num:生成數列個數,預設是50個
endpoint:如果為True,則最後一個元素包含在序列中,預設為True
retstep:如果為True,則返回等差間距,預設False
dtype:資料型別,自動推斷,一般都會是浮點數

建立1-10之間12個等差數列

arr = np.linspace(1,10,12)
print(arr)

列印結果:

[ 1. 1.81818182 2.63636364 3.45454545 4.27272727 5.09090909
5.90909091 6.72727273 7.54545455 8.36363636 9.18181818 10. ]

等比數列:np.logspace(start,stop,num=50,endpoint=True,base=10.0,dtype=None)

start:基底的start次冪
stop:基底的stop次冪
num:生成數列個數,預設是50個
endpoint:如果為True,則最後一個元素包含在序列中,預設為True
base:基底,預設以10為底
dtype:資料型別,自動推斷,一般都會是浮點數

建立基底的1次方到基底的3次方的3個等比數列

arr = np.logspace(1,3,3)
print(arr)

列印結果:

[ 10. 100. 1000.]

建立基底的1次方到基底的10次方的10個等比數列,設基底為2

arr = np.logspace(1,10,10,base=2)
print(arr)

列印結果:

[ 2. 4. 8. 16. 32. 64. 128. 256. 512. 1024.]

建立特定形狀的矩陣

全0矩陣

建立3行4列的全0矩陣

arr = np.zeros((3,4))
print(arr)

列印結果:

[[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]]

全1矩陣

建立3行4列的全1矩陣

arr = np.ones((3,4))
print(arr)

列印結果:

[[1. 1. 1. 1.]
[1. 1. 1. 1.]
[1. 1. 1. 1.]]

空矩陣

建立3行4列的空矩陣

arr = np.empty((3,4))
print(arr)

列印結果:

[[1.91409885e-233 1.78018403e-306 6.23057349e-307 1.06811422e-306]
[1.24610383e-306 1.69118108e-306 8.06632139e-308 1.20160711e-306]
[1.69119330e-306 1.29062229e-306 1.29060531e-306 2.16443571e-312]]

空矩陣中的元素內容並不為空,而是未經初始化的垃圾值,也就是隨機產生的資料。

元素值相同的矩陣

建立3行4列元素值為9的矩陣

arr = np.full((3,4),9)
print(arr)

列印結果:

[[9 9 9 9]
[9 9 9 9]
[9 9 9 9]]

仿維度建立矩陣

不管是zeros(),ones(),empty(),full(),都提供得有仿維度建立矩陣的函式,分別為zeros_like(),ones_like(),empty_like(),full_like(),用於創建出與其他矩陣相同維度的矩陣。

list2 = [[0,1,2,3,4],[5,6,7,8,9]]
arr = np.zeros_like(list2)
print(arr)

列印結果:

[[0 0 0 0 0]
[0 0 0 0 0]]

單位矩陣

生成4行4列的單位矩陣

arr = np.eye(4)
print(arr)

列印結果:

[[1. 0. 0. 0.]
[0. 1. 0. 0.]
[0. 0. 1. 0.]
[0. 0. 0. 1.]]

對角矩陣

生成對角元素為1、2、3、4的對角矩陣

arr = np.diag([1,2,3,4])
print(arr)

列印結果:

[[1 0 0 0]
 [0 2 0 0]
 [0 0 3 0]
 [0 0 0 4]]

建立隨機矩陣

生成0-1的隨機數矩陣

生成0到1之間的3行3列隨機矩陣

arr = np.random.random((3,3))
print(arr)

列印結果:

[[0.17461969 0.95103848 0.90655296]
[0.43783401 0.86078027 0.21500809]
[0.41657465 0.74977705 0.94805408]]

生成均勻分佈的隨機數

生成一個1-3之間的隨機數

arr = np.random.uniform(1,3)
print(arr)

列印結果:

1.719737091794529

生成12個1-3之間均勻分佈的隨機數

arr = np.random.uniform(1,3,12)
print(arr)

列印結果:

[1.61483448 1.9048385 1.13600459 1.45937536 2.94301615 2.57079044
1.51789902 2.36870025 1.53805667 1.77119578 1.14710285 1.28136849]

生成一個3行3列的1-3之間均勻分佈的隨機數二維矩陣

arr = np.random.uniform(1,3,(3,3))
print(arr)

列印結果:

[[1.12853188 1.62992154 1.08904213]
[2.3179576 2.80127557 2.59765234]
[2.58337986 2.46281735 1.69915473]]

生成標準正態的隨機數

生成一個3行3列的標準正態的隨機數二維矩陣

arr = np.random.randn(3,3)
print(arr)

列印結果:

[[-0.6659642  -0.14469211 -1.11157242]
 [-1.02770088  0.35732496 -0.74733868]
 [-2.30185962  0.05385927 -1.27661142]]

生成正態分佈的隨機數

本函式有3個引數:

第一個為正態分佈的均值,也就是正態分佈的中心對稱點。
第二個為正態分佈的標準差,標準差越大,影象越矮胖,標準差越小,影象越高瘦。
第三個為生成的矩陣形狀。

生成以1為均值2為標準差的3個隨機數

arr = np.random.normal(1,2,3)
print(arr)

列印結果:

[0.13655215 4.1985189 2.63631302]

生成以1為均值3為標準差的3行3列的隨機數矩陣

arr = np.random.normal(1,2,(3,3))
print(arr)

列印結果:

[[-0.94984175 0.9797389 -1.9574591 ]
[ 1.68702742 -0.1447021 0.80012014]
[-0.40085419 -1.56918216 -0.45392184]]

生成隨機整數

生成3行3列0-10之間的隨機整數矩陣

arr = np.random.randint(0,10,(3,3))
print(arr)

列印結果:

[[7 3 1]
[0 3 0]
[3 6 1]]

矩陣一般操作

矩陣擷取

矩陣擷取實際上就是融合了索引機制與切片機制,與list結構的擷取用法一樣。

生成一個5行5列的矩陣,作為本小節操作源。

np.random.seed(0) #設定隨機數種子 讓每次生成的隨機數都相同 方便測試
arr = np.random.randint(0,10,(5,5))
print(arr)

列印結果:

[[5 0 3 3 7]
[9 3 5 2 4]
[7 6 8 8 1]
[6 7 7 8 1]
[5 9 8 9 4]]

擷取矩陣第1行

a = arr[0]
print(a)

列印結果:

[5 0 3 3 7]

擷取矩陣最後一行

a = arr[-1]
print(a)

列印結果:

[5 9 8 9 4]

擷取矩陣最後兩行

a = arr[-2:]
print(a)

列印結果:

[[6 7 7 8 1]
[5 9 8 9 4]]

整個矩陣隔行擷取

a = arr[0::2]
print(a)

列印結果:

[[5 0 3 3 7]
[7 6 8 8 1]
[5 9 8 9 4]]

擷取矩陣第2行的第3列

a = arr[1,2]
print(a)

列印結果:

5

擷取矩陣前兩列

a = arr[:,0:2]
print(a)

列印結果:

[[5 0]
[9 3]
[7 6]
[6 7]
[5 9]]

按條件擷取

依然生成一個5行5列的矩陣,作為本小節操作源。

np.random.seed(0) #設定隨機數種子 讓每次生成的隨機數都相同 方便測試
arr = np.random.randint(0,10,(5,5))
print(arr)

列印結果:

[[5 0 3 3 7]
[9 3 5 2 4]
[7 6 8 8 1]
[6 7 7 8 1]
[5 9 8 9 4]]

以大於5為條件轉布林值矩陣

a = arr > 5
print(a)

列印結果:

[[False False False False True]
[ True False False False False]
[ True True True True False]
[ True True True True False]
[False True True True False]]

找出所有大於5的數

a = arr[arr > 5]
print(a)

列印結果:

[7 9 7 6 8 8 6 7 7 8 9 8 9]

矩陣中小於等於5的值置為0,其他不變

arr[arr <= 5] = 0
print(arr)

列印結果:

[[0 0 0 0 7]
[9 0 0 0 0]
[7 6 8 8 0]
[6 7 7 8 0]
[0 9 8 9 0]]

矩陣合併

生成兩個一樣的矩陣,作為本小節的示例源。

np.random.seed(0)
arr1 = arr2 = np.random.randint(0,10,(2,2))
print(arr1)

列印結果:

[[5 0]
[3 3]]

矩陣拉直合併

arr3 = np.append(arr1,arr2)
print(arr3)

列印結果:

[5 0 3 3 5 0 3 3]

矩陣橫向合併

arr3 = np.hstack([arr1,arr2])
print(arr3)

列印結果:

[[5 0 5 0]
[3 3 3 3]]

矩陣縱向合併

arr3 = np.vstack([arr1,arr2])
print(arr3)

列印結果:

[[5 0]
[3 3]
[5 0]
[3 3]]

矩陣運算

普通運算

普通運算有如下幾種:

加法 + 矩陣各元素對應相加
減法 - 矩陣各元素對應相減
乘法 * 矩陣各元素對應相乘
除法 / 矩陣各元素對應相除
取餘 % 矩陣各元素對應相除後取餘
冪運算 ** 矩陣各元素對應冪運算

建立一個3行3列的矩陣,用來作為本小節的操作源。

np.random.seed(0)
arr1 = np.random.randint(0,10,(3,3))
print(arr1)

列印結果:

[[5 0 3]
[3 7 9]
[3 5 2]]

加法

arr2 = arr1 + 10
print(arr2)

列印結果:

[[15 10 13]
[13 17 19]
[13 15 12]]

平方

arr2 = arr1 ** 2
print(arr2)

列印結果:

[[25 0 9]
[ 9 49 81]
[ 9 25 4]]

矩陣乘法

矩陣乘法要滿足矩陣乘法的條件:第一個矩陣的列數要等於第二個矩陣的行數才可以進行乘法計算

計算規則是,第一個矩陣的每行的每個數字與第二個矩陣的每列的每個數字對應相乘再相加,計算結果是第一個矩陣的行數第二個矩陣的列數所對應的值。

比如矩陣A:

2 3
4 5

矩陣B:

1 2
3 4

AB兩矩陣相乘,得到新矩陣C

C11:2*1 + 3*3 = 11
C12:2*2 + 3*4 = 16
C21:4*1 + 5*3 = 19
C22:4*2 + 5*4 = 28

也就是:

11 16
19 28

arr1 = np.array([[2,3],[4,5]])
print(arr1)

arr2 = np.array([[1,2],[3,4]])
print(arr2)

arr3 = np.dot(arr1,arr2)
print(arr3)

列印結果:

[[2 3]
 [4 5]]
[[1 2]
 [3 4]]
[[11 16]
 [19 28]]

矩陣轉置

np.transpose和arr.T效果相同,只適用於一維矩陣和二維矩陣。

arr = np.random.randint(1,10,(3,3))
print(arr)
print(np.transpose(arr))
print(arr.T)

列印結果:

[[9 7 5]
[1 9 6]
[3 3 4]]
[[9 1 3]
[7 9 3]
[5 6 4]]
[[9 1 3]
[7 9 3]
[5 6 4]]

最大最小值

最大值函式為np.amax(),最小值函式為np.amin(),使用方法一模一樣,再次只演示最大值。

求矩陣最大值

arr = np.array([[0,1,2,3,4],[5,6,7,8,9]])
print(arr)
print(np.amax(arr))

列印結果:

[[0 1 2 3 4]
[5 6 7 8 9]]
9

求每行的最大值

arr = np.array([[0,1,2,3,4],[5,6,7,8,9]])
print(arr)
print(np.amax(arr,axis=1))

列印結果:

[[0 1 2 3 4]
[5 6 7 8 9]]
[4 9]

求每列的最大值

arr = np.array([[0,1,2,3,4],[5,6,7,8,9]])
print(arr)
print(np.amax(arr,axis=0))

列印結果:

[[0 1 2 3 4]
[5 6 7 8 9]]
[5 6 7 8 9]

計算均值

arr = np.array([[0,1,2,3,4],[5,6,7,8,9]])
print(arr)
print(np.mean(arr))

列印結果:

[[0 1 2 3 4]
[5 6 7 8 9]]
4.5

計算中位數

arr = np.array([[0,1,2,3,4],[5,6,7,8,9]])
print(arr)
print(np.median(arr))

列印結果:

[[0 1 2 3 4]
[5 6 7 8 9]]
4.5

計算標準差

arr = np.array([[0,1,2,3,4],[5,6,7,8,9]])
print(arr)
print(np.std(arr))

列印結果:

[[0 1 2 3 4]
[5 6 7 8 9]]
2.8722813232690143

計算方差

arr = np.array([[0,1,2,3,4],[5,6,7,8,9]])
print(arr)
print(np.var(arr))

列印結果:

[[0 1 2 3 4]
[5 6 7 8 9]]
8.25

持久化儲存

儲存為二進位制檔案

arr = np.array([[0,1,2,3,4],[5,6,7,8,9]])
np.save('binary',arr)

z = np.load('binary.npy')
print(z)

列印結果:

[[0 1 2 3 4]
[5 6 7 8 9]]

np.save方法如果指定的檔名不是.npy字尾的話,會自動追加.npy字尾。
np.save方法可以儲存任何維度的矩陣。

儲存為txt檔案

arr = np.array([[0,1,2,3,4],[5,6,7,8,9]])
np.savetxt('a.txt',arr,fmt="%d")

z = np.loadtxt('a.txt')
print(z)

列印結果:

[[0. 1. 2. 3. 4.]
[5. 6. 7. 8. 9.]]

np.savetxt方法只能儲存一維或二維矩陣。
np.savetxt方法的fmt引數需要指定儲存資料格式,不指定的話預設是保留18位小數點的浮點數。儲存整數用fmt="%d",保留4位小數點用fmt="%0.4f",儲存字串用fmt='%s'。
np.savetxt方法還可以傳入header引數和footer引數,用於新增檔案頭部和尾部的註釋資訊。
np.loadtxt方法讀取檔案預設接收為浮點數格式,可以使用dtype引數指定格式。

儲存為csv檔案

arr = np.array([[0,1,2,3,4],[5,6,7,8,9]])
np.savetxt('a.csv',arr,fmt="%d",delimiter=',')

z = np.loadtxt('a.csv',delimiter=',')
print(z)

列印結果:

[[0. 1. 2. 3. 4.]
[5. 6. 7. 8. 9.]]

儲存為csv檔案依然還是使用np.savetxt方法,只不過新增一個delimiter引數,指明每個資料之間以逗號分隔。