AI基礎:Numpy簡易入門
- 2019 年 12 月 5 日
- 筆記
本文提供最簡易的 Numpy 的入門教程,適合初學者。(黃海廣)
1.Numpy 簡易入門
NumPy(Numeric Python)提供了許多高級的數值編程工具,如:矩陣數據類型、矢量處理,以及精密的運算庫。專為進行嚴格的數字處理而產生。多為很多大型金融公司使用,以及核心的科學計算組織如:Lawrence Livermore,NASA 用其處理一些本來使用 C++,Fortran 或 Matlab 等所做的任務。
1.1 認識 NumPy 數組對象
Numpy 是一個用 python 實現的科學計算的擴展程序庫,包括:
- 1、一個強大的 N 維數組對象 Array;
- 2、比較成熟的(廣播)函數庫;
- 3、用於整合 C/C++和 Fortran 代碼的工具包;
- 4、實用的線性代數、傅里葉變換和隨機數生成函數。numpy 和稀疏矩陣運算包 scipy 配合使用更加方便。
import numpy as np # 導入NumPy工具包
data = np.arange(12).reshape(3, 4) # 創建一個3行4列的數組
data
array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]])
type(data)
numpy.ndarray
data.ndim # 數組維度的個數,輸出結果2,表示二維數組
2
data.shape # 數組的維度,輸出結果(3,4),表示3行4列
(3, 4)
data.size # 數組元素的個數,輸出結果12,表示總共有12個元素
12
data.dtype # 數組元素的類型,輸出結果dtype('int64'),表示元素類型都是int64
dtype('int32')
1.2 創建 NumPy 數組
import numpy as np
data1 = np.array([1, 2, 3]) # 創建一個一維數組
data1
array([1, 2, 3])
data2 = np.array([[1, 2, 3], [4, 5, 6]]) # 創建一個二維數組
data2
array([[1, 2, 3], [4, 5, 6]])
np.zeros((3, 4))#創建一個全0數組
array([[0., 0., 0., 0.], [0., 0., 0., 0.], [0., 0., 0., 0.]])
np.ones((3, 4))#創建全一數組
array([[1., 1., 1., 1.], [1., 1., 1., 1.], [1., 1., 1., 1.]])
np.empty((5, 2))# 創建全空數組,其實每個值都是接近於零的數
array([[ 6.95312756e-310, 2.12199579e-314], [ 2.12199579e-314, 4.94065646e-324], [ 0.00000000e+000, -7.06252554e-311], [ 0.00000000e+000, -8.12021073e-313], [ 1.29923372e-311, 2.07507571e-322]])
np.arange(1, 20, 5)
array([ 1, 6, 11, 16])
np.array([1, 2, 3, 4], float)
array([1., 2., 3., 4.])
np.ones((2, 3), dtype='float64')
array([[1., 1., 1.], [1., 1., 1.]])
1.3 ndarry 對象的數據類型
1.3.1 查看數據類型
data_one = np.array([[1, 2, 3], [4, 5, 6]])
data_one.dtype.name
'int32'
1.3.2 轉換數據類型
data = np.array([[1, 2, 3], [4, 5, 6]])
data.dtype
dtype('int32')
float_data = data.astype(np.float64) # 數據類型轉換為float64
float_data.dtype
dtype('float64')
float_data = np.array([1.2, 2.3, 3.5])
float_data
array([1.2, 2.3, 3.5])
int_data = float_data.astype(np.int64) # 數據類型轉換為int64
int_data
array([1, 2, 3], dtype=int64)
str_data = np.array(['1', '2', '3'])
int_data = str_data.astype(np.int64)
int_data
array([1, 2, 3], dtype=int64)
1.4 數組運算
1.4.1 向量化運算
import numpy as np
data1 = np.array([[1, 2, 3], [4, 5, 6]])
data2 = np.array([[1, 2, 3], [4, 5, 6]])
data1 + data2 # 數組相加
array([[ 2, 4, 6], [ 8, 10, 12]])
data1 * data2 # 數組相乘
array([[ 1, 4, 9], [16, 25, 36]])
data1 - data2 # 數組相減
array([[0, 0, 0], [0, 0, 0]])
data1 / data2 # 數組相除
array([[1., 1., 1.], [1., 1., 1.]])
1.4.2 數組廣播
numpy 數組間的基礎運算是一對一,也就是a.shape==b.shape
,但是當兩者不一樣的時候,就會自動觸發廣播機制,如下例子:
import numpy as np
arr1 = np.array([[0], [1], [2], [3]])
arr1.shape
(4, 1)
arr2 = np.array([1, 2, 3])
arr2.shape
(3,)
arr1 + arr2
array([[1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6]])
到這裡,我們來給出一張圖:

也可以看這張圖:

1.4.3 數組與標量間的運算
import numpy as np
data1 = np.array([[1, 2, 3], [4, 5, 6]])
data2 = 10
data1 + data2 # 數組相加
array([[11, 12, 13], [14, 15, 16]])
data1 * data2 # 數組相乘
array([[10, 20, 30], [40, 50, 60]])
data1 - data2 # 數組相減
array([[-9, -8, -7], [-6, -5, -4]])
data1 / data2 # 數組相除
array([[0.1, 0.2, 0.3], [0.4, 0.5, 0.6]])
1.5 ndarray 的索引和切片
1.5.1 整數索引和切片的基本使用
我們一起來來總結一下,看下面切片取值方式(對應顏色是取出來的結果):


import numpy as np
arr = np.arange(8) # 創建一個一維數組
arr
array([0, 1, 2, 3, 4, 5, 6, 7])
arr[5] # 獲取索引為5的元素
5
arr[3:5] # 獲取索引為3~5的元素,但不包括5
array([3, 4])
arr[1:6:2] # 獲取索引為1~6的元素,步長為2
array([1, 3, 5])
import numpy as np
arr2d = np.array([[1, 2, 3],[4, 5, 6],[7, 8, 9]]) # 創建二維數組
arr2d
array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
arr2d[1] # 獲取索引為1的元素
array([4, 5, 6])
arr2d[0, 1] # 獲取位於第0行第1列的元素
2
arr2d[:2]
array([[1, 2, 3], [4, 5, 6]])
arr2d[0:2, 0:2]
array([[1, 2], [4, 5]])
arr2d[1, :2]
array([4, 5])
1.5.2 花式(數組)索引的基本使用
import numpy as np
demo_arr = np.empty((4, 4)) # 創建一個空數組 for i in range(4): demo_arr[i] = np.arange(i, i + 4) # 動態地為數組添加元素
demo_arr
array([[0., 1., 2., 3.], [1., 2., 3., 4.], [2., 3., 4., 5.], [3., 4., 5., 6.]])
demo_arr[[0, 2]] # 獲取索引為[0,2]的元素
array([[0., 1., 2., 3.], [2., 3., 4., 5.]])
demo_arr[[1, 3], [1, 2]] # 獲取索引為(1,1)和(3,2)的元素
array([2., 5.])
1.5.3 布爾型
# 存儲學生姓名的數組 student_name = np.array(['Tom', 'Lily', 'Jack', 'Rose'])
student_name
array(['Tom', 'Lily', 'Jack', 'Rose'], dtype='<U4')
# 存儲學生成績的數組 student_score = np.array([[79, 88, 80], [89, 90, 92], [83, 78, 85], [78, 76, 80]])
student_score
array([[79, 88, 80], [89, 90, 92], [83, 78, 85], [78, 76, 80]])
# 對student_name和字符串「Jack」通過運算符產生一個布爾型數組 student_name == 'Jack'
array([False, False, True, False])
# 將布爾數組作為索引應用於存儲成績的數組student_score, # 返回的數據是True值對應的行 student_score[student_name=='Jack']
array([[83, 78, 85]])
student_score[student_name=='Jack', :1]
array([[83]])
1.6 數組的轉置和軸對稱
arr = np.arange(12).reshape(3, 4)
arr
array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]])
arr.T # 使用T屬性對數組進行轉置
array([[ 0, 4, 8], [ 1, 5, 9], [ 2, 6, 10], [ 3, 7, 11]])
arr = np.arange(16).reshape((2, 2, 4))
arr
array([[[ 0, 1, 2, 3], [ 4, 5, 6, 7]], [[ 8, 9, 10, 11], [12, 13, 14, 15]]])
arr.transpose(1, 2, 0) # 使用transpose()方法對數組進行轉置
array([[[ 0, 8], [ 1, 9], [ 2, 10], [ 3, 11]], [[ 4, 12], [ 5, 13], [ 6, 14], [ 7, 15]]])
arr
array([[[ 0, 1, 2, 3], [ 4, 5, 6, 7]], [[ 8, 9, 10, 11], [12, 13, 14, 15]]])
arr.swapaxes(1, 0) # 使用swapaxes方法對數組進行轉置
array([[[ 0, 1, 2, 3], [ 8, 9, 10, 11]], [[ 4, 5, 6, 7], [12, 13, 14, 15]]])
1.7 NumPy 通用函數
arr = np.array([4, 9, 16])
np.sqrt(arr)#開方
array([2., 3., 4.])
np.abs(arr)#求絕對值
array([ 4, 9, 16])
np.square(arr)#求平方
array([ 16, 81, 256], dtype=int32)
x = np.array([12, 9, 13, 15])
y = np.array([11, 10, 4, 8])
np.add(x, y) # 計算兩個數組的和
array([23, 19, 17, 23])
np.multiply(x, y) # 計算兩個數組的乘積
array([132, 90, 52, 120])
np.maximum(x, y) # 兩個數組元素級最大值的比較
array([12, 10, 13, 15])
np.greater(x, y) # 執行元素級的比較操作
array([ True, False, True, True])
1.8 利用 NumPy 數組進行數據處理
1.8.1 將條件邏輯轉為數組運算
arr_x = np.array([1, 5, 7])
arr_y = np.array([2, 6, 8])
arr_con = np.array([True, False, True])
result = np.where(arr_con, arr_x, arr_y)
result
array([1, 6, 7])
1.8.2 數組統計運算
arr = np.arange(10)
arr.sum() # 求和
45
arr.mean() # 求平均值
4.5
arr.min() # 求最小值
0
arr.max() # 求最大值
9
arr.argmin() # 求最小值的索引
0
arr.argmax() # 求最大值的索引
9
arr.cumsum() # 計算元素的累計和
array([ 0, 1, 3, 6, 10, 15, 21, 28, 36, 45], dtype=int32)
arr.cumprod() # 計算元素的累計積
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int32)
x = np.arange(1 , 16).reshape((3 , 5)) print(x)
[[ 1 2 3 4 5] [ 6 7 8 9 10] [11 12 13 14 15]]
np.diff(x,axis=1) #默認axis=1
array([[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]])
np.diff(x,axis=0)
array([[5, 5, 5, 5, 5], [5, 5, 5, 5, 5]])
np.floor([-0.6,-1.4,-0.1,-1.8,0,1.4,1.7])
array([-1., -2., -1., -2., 0., 1., 1.])
看到沒,負數取整,跟上述的 around 一樣,是向左!
np.ceil([1.2,1.5,1.8,2.1,2.0,-0.5,-0.6,-0.3])
array([ 2., 2., 2., 3., 2., -0., -0., -0.])
取上限!找這個小數的最大整數即可!
查找,利用 np.where 實現小於 0 的值用 0 填充嗎,大於 0 的數不變!
x = np.array([[1, 0], [2, -2], [-2, 1]]) print(x)
[[ 1 0] [ 2 -2] [-2 1]]
np.where(x>0,x,0)
array([[1, 0], [2, 0], [0, 1]])
1.8.3 數組排序
arr = np.array([[6, 2, 7], [3, 6, 2], [4, 3, 2]])
arr
array([[6, 2, 7], [3, 6, 2], [4, 3, 2]])
arr.sort()
arr
array([[2, 6, 7], [2, 3, 6], [2, 3, 4]])
arr = np.array([[6, 2, 7], [3, 6, 2], [4, 3, 2]])
arr
array([[6, 2, 7], [3, 6, 2], [4, 3, 2]])
arr.sort(0) # 沿着編號為0的軸對元素排序
arr
array([[3, 2, 2], [4, 3, 2], [6, 6, 7]])
1.8.4 檢索數組元素
arr = np.array([[1, -2, -7], [-3, 6, 2], [-4, 3, 2]])
arr
array([[ 1, -2, -7], [-3, 6, 2], [-4, 3, 2]])
np.any(arr > 0) # arr的所有元素是否有一個大於0
True
np.all(arr > 0) # arr的所有元素是否都大於0
False
1.8.5 唯一化及其他集合邏輯
arr = np.array([12, 11, 34, 23, 12, 8, 11])
np.unique(arr)
array([ 8, 11, 12, 23, 34])
np.in1d(arr, [11, 12])
array([ True, True, False, False, True, False, True])
1.9 線性代數模塊
arr_x = np.array([[1, 2, 3], [4, 5, 6]])
arr_y = np.array([[1, 2], [3, 4], [5, 6]])
arr_x.dot(arr_y) # 等價於np.dot(arr_x, arr_y)
array([[22, 28], [49, 64]])
1.10 隨機數模塊
import numpy as np
np.random.rand(3, 3) # 隨機生成一個二維數組
array([[0.90422833, 0.57874299, 0.36084718], [0.46674697, 0.59189161, 0.88876503], [0.51836003, 0.30765097, 0.79668824]])
np.random.rand(2, 3, 3) # 隨機生成一個三維數組
array([[[0.21438832, 0.58877977, 0.86120009], [0.15222229, 0.53060997, 0.0562486 ], [0.88035435, 0.32505223, 0.9045713 ]], [[0.32907094, 0.88987195, 0.34523123], [0.90645746, 0.61257549, 0.83944649], [0.2015535 , 0.84522463, 0.87759584]]])
import numpy as np
np.random.seed(0) # 生成隨機數的種子
np.random.rand(5) # 隨機生成包含5個元素的浮點數組
array([0.5488135 , 0.71518937, 0.60276338, 0.54488318, 0.4236548 ])
np.random.seed(0)
np.random.rand(5)
array([0.5488135 , 0.71518937, 0.60276338, 0.54488318, 0.4236548 ])
np.random.seed()
np.random.rand(5)
array([0.19299506, 0.41434116, 0.90011257, 0.37469705, 0.69775797])
備註:本文代碼可以在github下載
https://github.com/fengdu78/Data-Science-Notes/tree/master/2.numpy