人工智能之數據分析 numpy
第九章 數組運算
(文章目錄)
前言
NumPy 不僅提供了高效的多維數組(ndarray)結構,還內置了豐富的數組運算功能,包括基礎算術、比較邏輯、位運算、通用函數(ufunc)、矩陣與線性代數等。這些運算是向量化的,無需顯式循環,性能遠超純 Python。
下面系統講解 NumPy 的各類數組運算。
一、基礎算術運算(Element-wise Arithmetic)
NumPy 支持對數組進行逐元素(element-wise) 的四則運算和冪運算。
1. 基本運算符(支持廣播)
import numpy as np
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
print(a + b) # [5 7 9]
print(a - b) # [-3 -3 -3]
print(a * b) # [4 10 18]
print(a / b) # [0.25 0.4 0.5 ]
print(a ** 2) # [1 4 9]
print(a % 2) # [1 0 1]
2. 廣播(Broadcasting)示例
# 標量與數組運算
print(a + 10) # [11 12 13]
# 不同形狀但兼容的數組
A = np.array([[1, 2, 3],
[4, 5, 6]]) # shape (2,3)
B = np.array([10, 20, 30]) # shape (3,)
print(A + B)
# [[11 22 33]
# [14 25 36]] ← B 被廣播到每一行
✅ 廣播規則:從後往前對齊維度,缺失或為1的維度可擴展。
二、比較運算(Comparison)
返回布爾數組,常用於篩選。
a = np.array([1, 2, 3, 4])
b = np.array([1, 3, 2, 4])
print(a == b) # [ True False False True]
print(a != b) # [False True True False]
print(a > 2) # [False False True True]
print(np.equal(a, b)) # 等價於 a == b
多數組比較
# 找出三個數組中相等的位置
c = np.array([1, 3, 3, 4])
mask = (a == b) & (b == c)
print(mask) # [ True False True True]
三、邏輯運算(Logical Operations)
適用於布爾數組。
| 運算 | 函數 | 説明 |
|---|---|---|
| 與 | np.logical_and(x, y) 或 x & y |
元素級 AND |
| 或 | np.logical_or(x, y) 或 x \| y |
元素級 OR |
| 非 | np.logical_not(x) 或 ~x |
元素級 NOT |
| 異或 | np.logical_xor(x, y) |
XOR |
x = np.array([True, False, True])
y = np.array([True, True, False])
print(x & y) # [ True False False]
print(np.logical_and(x, y)) # 同上
print(~x) # [False True False]
⚠️ 注意:對非布爾數組使用
&,|會執行位運算(見下文),而非邏輯運算!
四、位運算(Bitwise Operations)
對整數類型的二進制位進行操作。
| 運算符 | 函數 | 説明 |
|---|---|---|
& |
np.bitwise_and |
按位與 |
\| |
np.bitwise_or |
按位或 |
^ |
np.bitwise_xor |
按位異或 |
~ |
np.invert |
按位取反 |
<< |
np.left_shift |
左移 |
>> |
np.right_shift |
右移 |
a = np.array([1, 2, 3]) # 二進制: 01, 10, 11
b = np.array([3, 2, 1]) # 11, 10, 01
print(a & b) # [1 2 1] → 01&11=01, 10&10=10, 11&01=01
print(a << 1) # [2 4 6] → 左移1位(×2)
💡 位運算常用於掩碼操作、圖像處理、嵌入式系統等。
五、通用函數(ufunc: Universal Functions)
ufunc 是 NumPy 的核心,提供向量化、快速、元素級的數學函數。
1. 常見數學 ufunc
x = np.array([0, np.pi/2, np.pi])
print(np.sin(x)) # [0.0, 1.0, ~0.0]
print(np.cos(x)) # [1.0, ~0.0, -1.0]
print(np.exp(x)) # [1.0, ~4.81, ~23.14]
print(np.log([1, np.e, np.e**2])) # [0. 1. 2.]
print(np.sqrt([4, 9, 16])) # [2. 3. 4.]
2. 累積與聚合 ufunc
a = np.array([1, 2, 3, 4])
print(np.add.reduce(a)) # 10(求和)
print(np.multiply.reduce(a))# 24(連乘)
print(np.add.accumulate(a)) # [1 3 6 10](前綴和)
3. 自定義 ufunc(高級)
# 將普通函數轉為 ufunc
def my_func(x, y):
return x**2 + y**2
my_ufunc = np.frompyfunc(my_func, 2, 1)
result = my_ufunc([1, 2], [3, 4]) # 返回 object 數組
⚠️
frompyfunc性能較低,僅用於無法向量化的場景。
六、矩陣與線性代數(numpy.linalg)
Ⅰ. 矩陣乘法
在 NumPy 中,矩陣(Matrix) 有兩種主要表示方式:
- **普通的二維
ndarray**(推薦方式) - 已棄用的
np.matrix類
下面將詳細講解這兩種方式,並重點説明**為什麼現代 NumPy 推薦使用 ndarray 而非 matrix**,以及如何高效進行矩陣運算。
np.matrix:歷史遺留(已棄用)
1. 創建方式
import numpy as np
# 從字符串、列表或 ndarray 創建
M = np.matrix([[1, 2], [3, 4]])
N = np.matrix('1 2; 3 4') # 字符串形式
print(M)
# [[1 2]
# [3 4]]
2. 特點
- 始終是二維的(即使你試圖 reshape)
- **
*表示矩陣乘法**(不是逐元素相乘) - 有
.I(逆)、.T(轉置)等屬性
A = np.matrix([[1, 2], [3, 4]])
B = np.matrix([[5, 6], [7, 8]])
print(A * B) # 矩陣乘法!
# [[19 22]
# [43 50]]
print(A.I) # 逆矩陣
print(A.T) # 轉置
3. ❌ 為什麼被棄用?
- 行為不一致:與
ndarray混用時容易出錯 - 維度限制:無法表示三維及以上張量(深度學習必需)
- 社區共識:NumPy 官方自 1.15 版本起標記為 deprecated,未來可能移除
📌 官方建議:**不要使用
np.matrix**,改用ndarray+@運算符。
✅ 推薦方式:使用二維 ndarray 表示矩陣
1. 創建矩陣(本質是 2D array)
A = np.array([[1, 2],
[3, 4]]) # shape: (2, 2)
B = np.arange(1, 5).reshape(2, 2)
# [[1 2]
# [3 4]]
2. 矩陣運算(使用標準 NumPy 函數和運算符)
| 操作 | 推薦寫法 | 説明 |
|---|---|---|
| 矩陣乘法 | A @ B 或 np.dot(A, B) |
Python 3.5+ 支持 @ |
| 逐元素乘法 | A * B |
默認行為 |
| 轉置 | A.T 或 A.transpose() |
|
| 逆矩陣 | np.linalg.inv(A) |
|
| 行列式 | np.linalg.det(A) |
|
| 解方程 Ax=b | np.linalg.solve(A, b) |
示例:
A = np.array([[1, 2],
[3, 4]], dtype=float)
B = np.array([[5, 6],
[7, 8]], dtype=float)
# 矩陣乘法
C = A @ B
print("A @ B =\n", C)
# 轉置
print("A.T =\n", A.T)
# 逆矩陣
A_inv = np.linalg.inv(A)
print("A⁻¹ =\n", A_inv)
print("A @ A⁻¹ ≈ I:\n", A @ A_inv) # 應接近單位矩陣
# 解線性方程組
b = np.array([5, 11])
x = np.linalg.solve(A, b)
print("Solution x =", x) # [1. 2.] → 1*1+2*2=5, 3*1+4*2=11
輸出:
A @ B =
[[19. 22.]
[43. 50.]]
A.T =
[[1. 3.]
[2. 4.]]
A⁻¹ =
[[-2. 1. ]
[ 1.5 -0.5]]
A @ A⁻¹ ≈ I:
[[1.0000000e+00 0.0000000e+00]
[8.8817842e-16 1.0000000e+00]]
Solution x = [1. 2.]
常用矩陣操作彙總(基於 ndarray)
1. 基本屬性
M = np.array([[1, 2, 3],
[4, 5, 6]])
print(M.ndim) # 2
print(M.shape) # (2, 3)
print(M.size) # 6
2. 特殊矩陣構造
# 零矩陣
Z = np.zeros((3, 3))
# 單位矩陣
I = np.eye(3) # 或 np.identity(3)
# 對角矩陣
D = np.diag([1, 2, 3])
# 隨機矩陣
R = np.random.rand(2, 2)
3. 矩陣分解(numpy.linalg)
A = np.array([[1, 2], [3, 4]], dtype=float)
# 特徵值分解
eigenvals, eigenvecs = np.linalg.eig(A)
# 奇異值分解 (SVD)
U, s, Vt = np.linalg.svd(A)
# QR 分解
Q, R = np.linalg.qr(A)
4. 範數與條件數
# L2 範數(譜範數)
norm_A = np.linalg.norm(A, 2)
# Frobenius 範數
fro_norm = np.linalg.norm(A, 'fro')
# 條件數
cond_num = np.linalg.cond(A)
廣播與矩陣運算的注意事項
1. 矩陣乘法維度必須匹配
A = np.random.rand(3, 4)
B = np.random.rand(4, 2)
C = A @ B # ✅ (3,4) @ (4,2) → (3,2)
# D = A @ A # ❌ (3,4) @ (3,4) → 維度不匹配!
2. 向量與矩陣相乘
A = np.array([[1, 2],
[3, 4]])
v = np.array([1, 2]) # shape: (2,) —— 一維向量
# 左乘:v^T A → 結果是行向量(一維)
result1 = v @ A # [7, 10]
# 右乘:A v → 結果是列向量(一維)
result2 = A @ v # [5, 11]
# 若需顯式列向量,用 reshape
v_col = v.reshape(-1, 1) # shape: (2, 1)
Av = A @ v_col # shape: (2, 1)
💡 NumPy 中的一維數組在矩陣乘法中自動視為行或列向量,非常靈活。
實際應用示例
📌 示例 1:線性迴歸(最小二乘解)
# 數據:X (n_samples, n_features), y (n_samples,)
X = np.array([[1, 1],
[1, 2],
[1, 3]]) # 添加偏置項
y = np.array([2, 3, 4])
# 正規方程:w = (X^T X)^{-1} X^T y
XTX_inv = np.linalg.inv(X.T @ X)
w = XTX_inv @ X.T @ y
print("Weights:", w) # [1. 1.] → y = 1 + 1*x
📌 示例 2:圖像仿射變換(旋轉矩陣)
theta = np.pi / 4 # 45度
R = np.array([[np.cos(theta), -np.sin(theta)],
[np.sin(theta), np.cos(theta)]]) # 旋轉矩陣
point = np.array([1, 0]) # x軸上的點
rotated = R @ point
print("Rotated point:", rotated) # [0.707, 0.707]
總結:矩陣操作最佳實踐
| 項目 | 推薦做法 |
|---|---|
| 數據結構 | 使用 np.array(二維),不要用 np.matrix |
| 矩陣乘法 | 用 @ 或 np.dot() |
| 轉置 | 用 .T |
| 逆矩陣 | 用 np.linalg.inv() |
| 解方程 | 用 np.linalg.solve()(比求逆更穩定高效) |
| 高維張量 | ndarray 支持任意維度,matrix 不支持 |
🔑 核心理念:**統一使用
ndarray**,通過@和linalg模塊完成所有矩陣運算,代碼更清晰、兼容性更好、性能更優。
Ⅱ. 常用線性代數函數(np.linalg)
NumPy 通過 np.dot 和 numpy.linalg 模塊支持線性代數運算。
| 函數 | 説明 |
|---|---|
np.linalg.inv(A) |
矩陣求逆 |
np.linalg.det(A) |
行列式 |
np.linalg.eig(A) |
特徵值與特徵向量 |
np.linalg.solve(A, b) |
解線性方程組 Ax = b |
np.linalg.norm(x) |
向量/矩陣範數(默認 L2) |
np.linalg.svd(A) |
奇異值分解 |
示例:解線性方程組
# 2x + y = 5
# x + 3y = 10
A = np.array([[2, 1],
[1, 3]])
b = np.array([5, 10])
x = np.linalg.solve(A, b)
print(x) # [1. 3.] → x=1, y=3
示例:計算矩陣的 Frobenius 範數
norm = np.linalg.norm(A, 'fro') # 或默認 ord=None
七、其他重要運算
1. 聚合函數(Reduction)
arr = np.array([[1, 2, 3],
[4, 5, 6]])
print(arr.sum()) # 21
print(arr.sum(axis=0)) # [5 7 9](按列求和)
print(arr.mean(axis=1)) # [2. 5.](每行均值)
print(np.std(arr)) # 標準差
print(np.max(arr)) # 最大值
2. 四捨五入
x = np.array([1.234, 2.567, 3.891])
print(np.round(x, 1)) # [1.2 2.6 3.9]
print(np.floor(x)) # [1. 2. 3.]
print(np.ceil(x)) # [2. 3. 4.]
八、小結:運算類型速查表
| 類型 | 示例函數/運算符 | 説明 |
|---|---|---|
| 算術 | + - * / ** % |
逐元素運算,支持廣播 |
| 比較 | == != > < >= <= |
返回布爾數組 |
| 邏輯 | & \| ~(布爾數組) |
邏輯與/或/非 |
| 位運算 | & \| ^ ~ << >>(整數) |
二進制位操作 |
| ufunc | np.sin, np.exp, np.sqrt |
向量化數學函數 |
| 矩陣乘法 | @, np.dot |
線性代數乘法 |
| 線性代數 | np.linalg.inv, solve, eig |
高級矩陣運算 |
| 聚合 | sum, mean, std, max |
沿軸歸約 |
九、注意事項
-
**區分
*與@**:A * B:逐元素相乘A @ B:矩陣乘法
-
廣播陷阱:
a = np.array([1, 2]) b = np.array([[1], [2]]) print(a + b) # shape (2,2) —— 小心意外廣播! -
整數溢出:
x = np.array([200], dtype=np.uint8) print(x * 2) # 144(200*2=400 → 溢出迴繞) -
除零警告:
np.seterr(divide='ignore', invalid='ignore') # 控制警告行為
後續
本文主要講述了numpy數組相關的運算。python過渡項目部分代碼已經上傳至gitee,後續會逐步更新,主要受時間原因限制,當然自己也可以克隆到本地學習拓展。
資料關注
公眾號:咚咚王 gitee:https://gitee.com/wy18585051844/ai_learning
《Python編程:從入門到實踐》 《利用Python進行數據分析》 《算法導論中文第三版》 《概率論與數理統計(第四版) (盛驟) 》 《程序員的數學》 《線性代數應該這樣學第3版》 《微積分和數學分析引論》 《(西瓜書)周志華-機器學習》 《TensorFlow機器學習實戰指南》 《Sklearn與TensorFlow機器學習實用指南》 《模式識別(第四版)》 《深度學習 deep learning》伊恩·古德費洛著 花書 《Python深度學習第二版(中文版)【純文本】 (登封大數據 (Francois Choliet)) (Z-Library)》 《深入淺出神經網絡與深度學習+(邁克爾·尼爾森(Michael+Nielsen)》 《自然語言處理綜論 第2版》 《Natural-Language-Processing-with-PyTorch》 《計算機視覺-算法與應用(中文版)》 《Learning OpenCV 4》 《AIGC:智能創作時代》杜雨+&+張孜銘 《AIGC原理與實踐:零基礎學大語言模型、擴散模型和多模態模型》 《從零構建大語言模型(中文版)》 《實戰AI大模型》 《AI 3.0》