學習 NumPy:數據處理與分析基礎
課程目標
- 建立 NumPy 的基本知識。
- 學習使用 NumPy 進行高效的陣列操作。
- 掌握 NumPy 的進階功能,如廣播、索引、數學運算、統計分析和結構化陣列。
- 能夠運用 NumPy 解決實際資料科學問題。
- 實作 COVID-19 數據分析與視覺化
課程大綱
- NumPy 簡介
- 什麼是 NumPy?
- NumPy 的優勢:高效的陣列運算
- 安裝 NumPy
- 導入 NumPy 模組
- 查看 NumPy 版本
- NumPy 陣列基礎
- NumPy 陣列 (ndarray) 的概念
- 從 Python List 建立 NumPy 陣列
- 建立不同維度的 NumPy 陣列
- 一維陣列
- 二維陣列
- 三維陣列
- NumPy 陣列的屬性
- 形狀 (shape)
- 維度 (ndim)
- 資料型態 (dtype)
- 大小 (size)
- 記憶體大小 (nbytes)
- NumPy 陣列的資料型態
- 創建特殊陣列
- np.zeros() 零陣列
- np.ones() 單位陣列
- np.arange() 等差陣列
- np.linspace() 線性等分陣列
- NumPy 陣列的索引與切片
- 存取單一元素
- 多維陣列的索引
- 切片操作
- 布林索引
- Fancy Indexing
- NumPy 陣列的運算
- 基本算術運算 (+, -, *, /)
- Universal Functions (ufuncs)
- 平方 (square)
- 平方根 (sqrt)
- 指數 (exp)
- 對數 (log)
- 三角函數 (sin, cos, tan)
- 聚合運算
- 總和 (sum)
- 平均值 (mean)
- 中位數 (median)
- 標準差 (std)
- 最大值 (max)
- 最小值 (min)
- NumPy 的廣播 (Broadcasting)
- 廣播的概念與用途
- 廣播的規則
- 廣播的實際應用
- NumPy 的進階應用
- 陣列的重塑 (reshape)
- 陣列的合併與分割
- 水平合併 (hstack)
- 垂直合併 (vstack)
- 分割 (split)
- 條件篩選與布林邏輯
- 使用布林運算篩選陣列元素
- np.where() 函數
- 排序
- np.sort() 函數
- np.argsort() 函數
- NumPy 的結構化陣列
- 結構化陣列的概念
- 定義結構化陣列的資料型態
- 建立結構化陣列
- 存取結構化陣列的欄位
- 使用結構化陣列進行資料分析
- NumPy 實例演練
- 計算移動平均
- 數據標準化
- 線性回歸分析
- 圖像處理
- COVID-19 數據分析與可視化
課程內容詳解
1. NumPy 簡介
NumPy(Numerical Python 的簡稱)是 Python 中用於科學計算的核心函式庫。它提供了一個高性能的多維陣列對象 ndarray
,以及用於處理這些陣列的工具。
NumPy 的優勢:
- 高效的陣列運算:NumPy 的底層使用 C 語言編寫,對陣列的運算速度非常快。
- 豐富的數學函數:NumPy 提供了大量的數學函數,可以方便地進行各種數值計算。
- 廣播 (Broadcasting) 功能:NumPy 允許不同形狀的陣列進行運算,簡化了程式碼的編寫。
- 方便的索引和切片:NumPy 提供了靈活的索引和切片功能,可以方便地存取和操作陣列中的元素。
安裝 NumPy:
pip install numpy
導入 NumPy 模組:
import numpy as np
查看 NumPy 版本:
print("NumPy 版本:", np.__version__)
2. NumPy 陣列基礎
NumPy 陣列是 NumPy 的核心資料結構,它是一個由相同資料型態元素組成的多維網格。
從 Python List 建立 NumPy 陣列:
py_list = [1, 2, 3, 4, 5]
np_array = np.array(py_list)
print("Python List:", py_list)
print("NumPy Array:", np_array)
建立不同維度的 NumPy 陣列:
# 一維陣列
array1 = np.array([1, 2, 3, 4])
print("一維陣列:", array1)
# 二維陣列
array2 = np.array([[1, 2, 3], [4, 5, 6]])
print("二維陣列:\n", array2)
# 三維陣列
array3D = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
print("三維陣列:\n", array3D)
NumPy 陣列的屬性:
array = np.array([[1, 2, 3], [4, 5, 6]])
print("陣列形狀 (shape):", array.shape) # 輸出:(2, 3)
print("陣列維度 (ndim):", array.ndim) # 輸出:2
print("陣列資料型態 (dtype):", array.dtype) # 輸出:int64 (取決於系統)
print("陣列大小 (size):", array.size) # 輸出:6
print("陣列記憶體大小 (nbytes):", array.nbytes) # 輸出:48 (6 * 8,int64 佔 8 個 byte)
NumPy 陣列的資料型態: NumPy 陣列中的元素必須具有相同的資料型態。NumPy 支援多種資料型態,例如:
int
: 整數float
: 浮點數bool
: 布林值string
: 字串
創建特殊陣列:
# 創建零陣列
zeros_array = np.zeros((3, 4), dtype=int)
print("零陣列:\n", zeros_array)
# 創建單位陣列
ones_array = np.ones((3, 4), dtype=int)
print("單位陣列:\n", ones_array)
# 創建等差數列
arange_array = np.arange(0, 10, 2) # 從 0 開始,到 10 結束(不包含 10),步長為 2
print("等差數列:", arange_array)
# 創建線性等分陣列
linspace_array = np.linspace(0, 1, 5) # 從 0 到 1,平均分為 5 份
print("線性等分陣列:", linspace_array)
3. NumPy 陣列的索引與切片
NumPy 提供了靈活的索引和切片功能,可以方便地存取和操作陣列中的元素。
array = np.array([[1, 2, 3], [4, 5, 6]])
# 存取單一元素
print(array[0, 0]) # 輸出:1
# 切片操作
print(array[0, :]) # 輸出:[1 2 3] (第一行)
print(array[:, 1]) # 輸出:[2 5] (第二列)
# 布林索引
mask = array > 3
print(array[mask]) # 輸出:[4 5 6]
# Fancy Indexing
indices = [0, 2]
print(np.array([1, 2, 3, 4, 5])[indices]) # 輸出:[1 3]
4. NumPy 陣列的運算
NumPy 提供了大量的數學函數,可以方便地進行各種數值計算。
array = np.array([1, 2, 3])
# 基本算術運算
print(array + 1) # 輸出:[2 3 4]
print(array * 2) # 輸出:[2 4 6]
# Universal Functions (ufuncs)
print(np.square(array)) # 輸出:[1 4 9]
print(np.sqrt(array)) # 輸出:[1. 1.41421356 1.73205081]
# 聚合運算
print(np.sum(array)) # 輸出:6
print(np.mean(array)) # 輸出:2.0
5. NumPy 的廣播 (Broadcasting)
廣播允許不同形狀的陣列進行運算。NumPy 會自動將較小的陣列“擴展”到較大的陣列形狀,以便進行逐元素運算。
a = np.array([[1, 2], [3, 4]])
b = np.array([10, 20])
print(a + b)
# 輸出:
# [[11 22]
# [13 24]]
6. NumPy 的進階應用
array = np.array([1, 2, 3, 4, 5, 6])
# 陣列的重塑 (reshape)
new_array = array.reshape(2, 3)
print(new_array)
# 輸出:
# [[1 2 3]
# [4 5 6]]
# 陣列的合併 (hstack)
array1 = np.array([1, 2, 3])
array2 = np.array([4, 5, 6])
merged_array = np.hstack((array1, array2))
print(merged_array) # 輸出:[1 2 3 4 5 6]
# 條件篩選 (where)
array = np.array([1, 2, 3, 4, 5])
new_array = np.where(array > 3, array, 0) # 大於 3 的元素保留,否則設為 0
print(new_array) # 輸出:[0 0 0 4 5]
# 排序 (sort)
array = np.array([3, 1, 4, 1, 5, 9, 2, 6])
sorted_array = np.sort(array)
print(sorted_array) # 輸出:[1 1 2 3 4 5 6 9]
7. NumPy 的結構化陣列
結構化陣列允許您儲存具有不同資料型態的資料。
dtype = [('name', 'U10'), ('age', 'i4'), ('height', 'f4')]
data = np.array([('Alice', 25, 160.5), ('Bob', 30, 175.2)], dtype=dtype)
print(data['name']) # 輸出:['Alice' 'Bob']
print(data[data['age'] > 26]) # 輸出年齡大於26的
8. NumPy 實例演練
# 計算移動平均
def moving_average(arr, window_size):
return np.convolve(arr, np.ones(window_size)/window_size, mode='valid')
data_series = np.array
([1, 2, 3, 4, 5, 6, 7, 8, 9])
result = moving_average(data_series, 3)
print(result)
COVID-19 數據分析與可視化
import numpy as np
import os
import matplotlib.pyplot as plt
from numpy import ma
# 1. 設置文件路徑
filepath = os.getcwd()
filename = os.path.join(filepath, "who_covid_19_sit_rep_time_series.csv")
# 2. 讀取數據
dates = np.genfromtxt(filename, dtype=np.unicode_, delimiter=",", max_rows=1, usecols=range(4, 18), encoding="utf-8-sig")
locations = np.genfromtxt(filename, dtype=np.unicode_, delimiter=",", skip_header=6, usecols=(0, 1), encoding="utf-8-sig")
nbcases = np.genfromtxt(filename, dtype=np.int_, delimiter=",", skip_header=6, usecols=range(4, 18), encoding="utf-8-sig")
# 3. 清除“總計”行
totals_row = 35
locations = np.delete(locations, (totals_row), axis=0)
nbcases = np.delete(nbcases, (totals_row), axis=0)
# 4. 提取中國的累積病例數據
china_mask = ((locations[:, 1] == "China") & (locations[:, 0] != "Hong Kong") & (locations[:, 0] != "Taiwan") & (locations[:, 0] != "Macau") & (locations[:, 0] != "Unspecified*"))
nbcases_ma = ma.masked_values(nbcases, -1)
china_total = nbcases_ma[china_mask].sum(axis=0)
# 5. 數據擬合與預測
t = np.arange(len(china_total))
model = np.polynomial.Polynomial.fit(t[~china_total.mask], china_total[~china_total.mask], deg=3)
# 6. 繪製數據圖表
plt.plot(t, china_total, "o-", label="Mainland China Cases")
plt.plot(t, model(t), "--", label="Cubic Estimate")
plt.plot(7, model(7), "r*", label="7 Days After Start")
plt.xticks([0, 7, 13], dates[[0, 7, 13]])
plt.xlabel("Date")
plt.ylabel("Cumulative Cases")
plt.title("COVID-19 Cumulative Cases in Mainland China")
plt.legend()
plt.grid(True)
plt.show()