1. NumPy 套件 (入門)
日期:2024/04/14
1. NumPy 套件 (入門)
Python 在處理資料數據領域非常流行,有許多強大的套件和工具可供使用。
以下是 Python 資料科學中常用的一些主要庫和工具:
NumPy: Python語言的一個擴充程式庫。支援高階大規模的多維陣列與矩陣運算,此外也針對陣列運算提供大量的數學函式函式庫。NumPy 在底層是 C 語言在計算上會更加快素。
Pandas: Pandas 是用於資料操作和分析的重要庫。它提供了高性能、易於使用的資料結構(如 DataFrame 和 Series),以及各種資料操作功能,包括資料索引、過濾、合併、重塑和分組等。也有人稱它為 Python 界的 Excel。
學會資料科學資料科學家、資料分析師 、資料工程師都是可能的出路。
本章節將採用 Anaconda 及 Jupyter notebook 請各位先行安裝。
Anaconda 預設把大部分資料科學需要的工具及套件皆安裝好,不用額外安裝設定。
1.1 NumPy
NumPy 是以連續存儲的數據塊,並且它們使用固定大小的數據類型,這使得 NumPy 能夠以高效的方式進行數組操作和數學計算。此外,NumPy 使用了稱為通用函數(ufuncs)的機制,這使得它能夠對所有元素同時進行運算,而無需逐一計算。
由於這些原因,使用 NumPy 庫進行數據處理和科學計算通常比純 Python 代碼更快。特別是當處理大型數據集時,NumPy 的性能優勢更加顯著。因此,許多數據科學和機器學習項目都會使用 NumPy 來提高計算效率。
我們使用下程式做個小實驗
import numpy as npimport timenum = 10000000my_array = np.arange(num) # NumPy 陣列,值:[0, num)my_list = list(range(num)) # Python 串列,值:[0, num)startTime = time.time()my_array2 = my_array * 2endTime = time.time()print('NumPy array multiplication time:', endTime - startTime)startTime = time.time()my_list2 = [x*2 for x in my_list]endTime = time.time()print('Python list comprehension time:', endTime - startTime)
- NumPy array multiplication time: 0.013138055801391602
- Python list comprehension time: 0.32367682456970215
此例子兩者速度相差 25 倍左右!
Jupyter Notebook
import numpy as npnum = 10000000my_array = np.arange(num) # NumPy 陣列,值:[0, num)my_list = list(range(num)) # Python 串列,值:[0, num)%time my_array2 = my_array * 2%time my_list2 = [x*2 for x in my_list]
- CPU times: user 3.72 ms, sys: 59.5 ms, total: 63.3 ms
- Wall time: 63.4 ms
- CPU times: user 290 ms, sys: 115 ms, total: 406 ms
- Wall time: 406 ms
在 Jupyter Notebook 中,%time 是一個稱為魔法命令的功能之一,用於測試單個程式的執行時間。這個魔法命令可以用來評估程式的效率,幫助您優化程式。
- CPU times::程式在 CPU 上所執行的時間
- user:CPU 在執行程式的時間。
- sys:CPU 花費在系統內核(kernel)指令上的時間,這個時間包括了 CPU 花費在系統調用、文件 IO 等系統操作上的時間。
- Wall time: 程式執行所用的實際時間
導入 NumPy
依照慣例大家會將 numpy 改名為 np
import numpy as np
創建 NumPy 數組
# 創建一個一維陣列arr1d = np.array([1, 2, 3, 4, 5])print(arr1d)# 創建一個二維陣列arr2d = np.array([[1, 2, 3], [4, 5, 6]])print(arr2d)
[1 2 3 4 5]
[[1 2 3]
[4 5 6]]
常用屬性和方法
arr2d以圖表呈現如下
| 1 | 2 | 3 |
| 4 | 5 | 6 |
ndim: 返回數組的維度。shape: 返回數組的形狀(各維度的大小)。dtype: 返回數組中元素的數據類型。size: 返回數組中元素的總數。
print("維度:", arr2d.ndim) # 維度: 2print("形狀:", arr2d.shape) # 形狀: (2, 3)print("數據類型:", arr2d.dtype) # 數據類型: int64print("元素總數:", arr2d.size) # 元素總數: 6
產生 ndarray
np.zeros(): 生成全部為 0 的數組。np.ones(): 生成全部為 1 的數組。np.arange(): 類似於 Python 內置的 range() 函數。np.linspace(): 在指定的範圍內生成均勻間隔的數組。
zeros_arr = np.zeros((2, 3)) # 生成一個 2x3 的全為 0 的數組print(zeros_arr)# [[0. 0. 0.]# [0. 0. 0.]]ones_arr = np.ones((3, 2)) # 生成一個 3x2 的全為 1 的數組print(ones_arr)# [[1. 1.]# [1. 1.]# [1. 1.]]range_arr = np.arange(1, 10, 2) # 生成一個從1到9,步長為2的數組print(range_arr)# [1 3 5 7 9]lin_arr = np.linspace(0, 1, 5) # 在0到1之間生成5個均勻分佈的數字print(lin_arr)# [0. 0.25 0.5 0.75 1. ]
新增、刪除和排序元素
np.append(arr, values, axis=None): 將內容添加陣列尾部。arr = np.array([2, 1, 5, 3, 7, 4, 6, 8])arr = np.append(arr, [7,8,9])print(arr)# [2 1 5 3 7 4 6 8 7 8 9]
arr = np.array([[1,2,3],[4,5,6]])arr = np.append(arr, [[7,8,9]], axis=0)print(arr)# [[1 2 3]# [4 5 6]# [7 8 9]]
arr = np.array([[1,2,3],[4,5,6]])arr = np.append(arr, [[7, 8, 9],[10, 11, 12]], axis=1)print(arr)# [[ 1 2 3 7 8 9]# [ 4 5 6 10 11 12]]
numpy.delete(arr, obj, axis=None): 刪除指定索引或切片的元素。arr = np.array([1, 2, 3, 4, 5])arr = np.delete(arr, 2) # 刪除索引為2的元素print(arr) # [1 2 4 5]
np.sort(): 將陣列內容從小到大排序,產生新的陣列。arr = np.array([2, 1, 5, 3, 7, 4, 6, 8])np.sort(arr)print(arr)# [1, 2, 3, 4, 5, 6, 7, 8]
np.concatenate(): 將兩個陣列組合。a = np.array([1, 2, 3, 4])b = np.array([5, 6, 7, 8])arr =np.concatenate((a, b))print(arr)# [1, 2, 3, 4, 5, 6, 7, 8]
x = np.array([[1, 2], [3, 4]])y = np.array([[5, 6]])arr = np.concatenate((x, y), axis=0)print(arr)# [[1, 2],# [3, 4],# [5, 6]])
形狀變換
reshape():用於改變陣列的形狀,但它返回一個新的陣列,必須確保新形狀與原始陣列中的元素數量相同。
# 創建一個一維陣列arr = np.array([1, 2, 3, 4, 5, 6])# 使用 reshape() 將其轉換為 2x3 的二維陣列arr_reshaped = arr.reshape(2, 3)print(arr)# [1 2 3 4 5 6]
resize():於改變陣列的形狀,但它會直接修改原始陣列。如果新形狀比原始陣列中的元素數量大,則會用 0 填充多出的部分;如果新形狀比原始陣列中的元素數量小,則會截斷陣列。
# 創建一個一維陣列arr = np.array([1, 2, 3, 4, 5, 6])# 使用 resize() 將其改變形狀為 2x4 的二維陣列(修改原始陣列)arr.resize(2, 4)print(arr)# [[1 2 3 4]# [5 6 0 0]]
.T:矩陣轉置,將欄和列互換。
# 建立一個矩陣matrix = np.array([[1, 2, 3],[4, 5, 6]])transposed_matrix = matrix.Tprint(transposed_matrix)# [[1 4]# [2 5]# [3 6]]
索引和切片
這邊與一般 python list 操作一致
# 創建一個一維陣列arr = np.array([1, 2, 3, 4, 5])# 使用索引訪問單個元素print(arr[0]) # 1# 使用索引訪問多個元素print(arr[[3, 1, 0]]) # [4 2 1]# 使用負索引訪問最後一個元素print(arr[-1]) # 5# 使用切片訪問範圍內的元素(左閉右開區間)print(arr[1:3]) # [2 3]# 省略開始索引,從開頭訪問到索引2(不包括2)print(arr[:3]) # [1 2 3]# 省略結束索引,從索引1開始到結尾print(arr[1:]) # [2 3 4 5]# 使用負索引進行切片print(arr[:-1]) # [1 2 3 4]
# 創建一個二維陣列arr_2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])# 使用索引訪問多個元素print(arr_2d[0, 0]) # 1# 使用索引訪問單個元素print(arr_2d[[2, 0]])# [[7 8 9]# [1 2 3]]# 使用切片訪問子陣列print(arr_2d[1:, :2])# [[4 5]# [7 8]]
數學運算
# 創建兩個陣列arr1 = np.array([[1, 2], [3, 4]])arr2 = np.array([[5, 6], [7, 8]])
- 基本的算術運算
# 加法print(arr1 + arr2)# [[ 6 8]# [10 12]]# 減法print(arr1 - arr2)# [[-4 -4]# [-4 -4]]# 乘法(元素級別)print(arr1 * arr2)# [[ 5 12]# [21 32]]# 除法(元素級別)print(arr1 / arr2)# [[0.2 0.33333333]# [0.42857143 0.5 ]]
- 統計運算
# 求和print(np.sum(arr1)) # 10# 求每一行的和print(np.sum(arr1, axis=1)) # [3 7]# 求每一列的和print(np.sum(arr1, axis=0)) # [4 6]# 求平均值print(np.mean(arr1)) # 2.5# 求最大值print(np.max(arr1)) # 4# 求最小值print(np.min(arr1)) # 1
線性代數運算
from numpy.linalg import invarr1 = np.array([[1, 2], [3, 4]])arr2 = np.array([[5, 6], [7, 8]])# 矩陣乘法print(np.dot(arr1, arr2))# [[19 22]# [43 50]]# 行列式print(np.linalg.det(arr1)) # -2.0000000000000004# 反矩陣print(np.linalg.inv(arr1))# [[-2. 1. ]# [ 1.5 -0.5]]# 特徵值和特徵向量eigenvalues, eigenvectors = np.linalg.eig(arr1)print("特徵值:", eigenvalues)# 特徵值: [-0.37228132 5.37228132]print("特徵向量:", eigenvectors)# 特徵向量: [[-0.82456484 -0.41597356]# [ 0.56576746 -0.90937671]]
當然還有很多的用法本章節僅提及比較常用的。
