NumPy矩阵操作

一、基本矩阵操作

1. 创建矩阵

python

import numpy as np

# 从列表创建
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])

# 特殊矩阵
zeros = np.zeros((3, 3))      # 3x3零矩阵
ones = np.ones((2, 2))        # 2x2单位矩阵
identity = np.eye(3)          # 3x3单位矩阵
diag = np.diag([1, 2, 3])     # 对角矩阵
'''
[[1 0 0]
 [0 2 0]
 [0 0 3]]
'''

2. 矩阵属性

python

A = np.array([[1, 2, 3], [4, 5, 6]])

print(A.shape)      # (2, 3) → 维度
print(A.ndim)       # 2 → 秩(维度数)
print(A.size)       # 6 → 元素总数
print(A.dtype)      # int64 → 数据类型
print(A.T)          # 转置

二、矩阵运算

1. 算术运算(逐元素)

python

A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])

print(A + B)        # 逐元素加法
'''
[[ 6  8]
 [10 12]]
'''

print(A * B)        # 逐元素乘法(哈达玛积)
'''
[[ 5 12]
 [21 32]]
'''

print(A ** 2)       # 逐元素平方
print(np.sqrt(A))   # 逐元素开方

2. 真正的矩阵乘法

python

A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])

# 方法1:使用@运算符(推荐)
print(A @ B)
'''
[[19 22]
 [43 50]]
'''

# 方法2:使用dot函数
print(np.dot(A, B))

# 方法3:使用matmul函数
print(np.matmul(A, B))

# 方法4:使用dot方法
print(A.dot(B))

3. 矩阵乘法的维度要求

python

# 矩阵A (m×n) 乘以 矩阵B (n×p) 得到 (m×p)
A = np.random.rand(3, 4)  # 3x4
B = np.random.rand(4, 5)  # 4x5
C = A @ B  # 3x5

# 错误示例
# D = B @ A  # 报错!4x5 不能乘以 3x4

三、线性代数运算

1. 逆矩阵

python

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

# 求逆
A_inv = np.linalg.inv(A)
print(A_inv)
'''
[[-2.   1. ]
 [ 1.5 -0.5]]
'''

# 验证:A × A⁻¹ = I
print(A @ A_inv)  # 近似单位矩阵

2. 行列式

python

A = np.array([[1, 2], [3, 4]])
det = np.linalg.det(A)
print(det)  # -2.0

3. 特征值和特征向量

python

A = np.array([[1, 2], [2, 1]])

eigenvalues, eigenvectors = np.linalg.eig(A)
print("特征值:", eigenvalues)    # [ 3. -1.]
print("特征向量:\n", eigenvectors)
'''
[[ 0.70710678 -0.70710678]
 [ 0.70710678  0.70710678]]
'''

4. 矩阵的迹

python

A = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
trace = np.trace(A)  # 对角线元素之和
print(trace)  # 15 (1+5+9)

5. 矩阵的秩

python

A = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
rank = np.linalg.matrix_rank(A)
print(rank)  # 2(第三行是第一、二行的线性组合)

四、分解操作

1. LU分解

python

A = np.array([[2, 5, 8], [5, 3, 1], [7, 9, 4]])

P, L, U = scipy.linalg.lu(A)  # 需要SciPy
print("P (置换矩阵):\n", P)
print("L (下三角):\n", L)
print("U (上三角):\n", U)

2. QR分解

python

A = np.array([[1, 2], [3, 4], [5, 6]])

Q, R = np.linalg.qr(A)
print("Q (正交矩阵):\n", Q)
print("R (上三角):\n", R)

3. SVD分解

python

A = np.array([[1, 2], [3, 4], [5, 6]])

U, S, Vh = np.linalg.svd(A)
print("U:\n", U)
print("奇异值:", S)
print("Vh:\n", Vh)

五、求解线性方程组

1. 唯一解

python

# 解 Ax = b
A = np.array([[3, 1], [1, 2]])
b = np.array([9, 8])

# 方法1:使用solve
x = np.linalg.solve(A, b)
print(x)  # [2., 3.]

# 验证
print(A @ x)  # [9., 8.] = b

2. 最小二乘解

python

# 当A不是方阵或方程组超定时
A = np.array([[1, 1], [1, 2], [1, 3]])
b = np.array([1, 3, 2])

x, residuals, rank, s = np.linalg.lstsq(A, b, rcond=None)
print("最小二乘解:", x)  # [0.66666667, 0.5]

六、范数和条件数

1. 矩阵范数

python

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

print("Frobenius范数:", np.linalg.norm(A, 'fro'))  # 5.477
print("1-范数:", np.linalg.norm(A, 1))  # 6.0
print("2-范数:", np.linalg.norm(A, 2))  # 5.465
print("无穷范数:", np.linalg.norm(A, np.inf))  # 7.0

2. 条件数

python

A = np.array([[1, 2], [3, 4]])
cond = np.linalg.cond(A)
print("条件数:", cond)  # 14.933

七、特殊矩阵操作

1. 矩阵拼接

python

A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])

# 水平拼接
C = np.hstack([A, B])
print(C)
'''
[[1 2 5 6]
 [3 4 7 8]]
'''

# 垂直拼接
D = np.vstack([A, B])
print(D)
'''
[[1 2]
 [3 4]
 [5 6]
 [7 8]]
'''

# 深度方向拼接
E = np.dstack([A, B])
print(E.shape)  # (2, 2, 2)

2. 矩阵分块

python

A = np.arange(16).reshape(4, 4)
'''
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]
 [12 13 14 15]]
'''

# 提取子矩阵
top_left = A[:2, :2]      # [[0 1], [4 5]]
bottom_right = A[2:, 2:]  # [[10 11], [14 15]]

3. 矩阵广播

python

A = np.array([[1, 2, 3],
              [4, 5, 6],
              [7, 8, 9]])

# 行向量广播
row_vector = np.array([1, 0, -1])
print(A + row_vector)
'''
[[ 2  2  2]
 [ 5  5  5]
 [ 8  8  8]]
'''

# 列向量广播
col_vector = np.array([[1], [0], [-1]])
print(A + col_vector)
'''
[[ 2  3  4]
 [ 4  5  6]
 [ 6  7  8]]
'''

八、统计操作

1. 矩阵统计

python

A = np.array([[1, 2, 3],
              [4, 5, 6],
              [7, 8, 9]])

print("每列的和:", A.sum(axis=0))     # [12 15 18]
print("每行的均值:", A.mean(axis=1))   # [2. 5. 8.]
print("最大值:", A.max())             # 9
print("最小值的位置:", A.argmin())     # 0

2. 协方差矩阵

python

# 计算数据集的协方差矩阵
data = np.array([[1, 2, 3],
                 [4, 5, 6],
                 [7, 8, 9]])

cov_matrix = np.cov(data.T)  # 转置后每列是一个变量
print(cov_matrix)
'''
[[9. 9. 9.]
 [9. 9. 9.]
 [9. 9. 9.]]
'''

九、实用示例

1. 线性回归

python

# y = Xβ + ε,求解β
X = np.array([[1, 1], [1, 2], [1, 3], [1, 4]])
y = np.array([2, 3, 5, 7])

# 正规方程:β = (XᵀX)⁻¹Xᵀy
XTX_inv = np.linalg.inv(X.T @ X)
beta = XTX_inv @ X.T @ y
print("回归系数:", beta)  # [0.5, 1.6]

2. PCA主成分分析

python

# 数据中心化
data = np.random.randn(100, 3)
data_centered = data - data.mean(axis=0)

# 计算协方差矩阵
cov_matrix = np.cov(data_centered.T)

# 特征值分解
eigenvalues, eigenvectors = np.linalg.eig(cov_matrix)

# 选择主成分
sorted_idx = np.argsort(eigenvalues)[::-1]
principal_components = eigenvectors[:, sorted_idx[:2]]

3. 图像变换矩阵

python

# 2D旋转矩阵
def rotation_matrix(theta):
    return np.array([[np.cos(theta), -np.sin(theta)],
                     [np.sin(theta), np.cos(theta)]])

# 缩放矩阵
def scaling_matrix(sx, sy):
    return np.array([[sx, 0], [0, sy]])

# 组合变换
R = rotation_matrix(np.pi/4)  # 旋转45度
S = scaling_matrix(2, 1)      # x方向放大2倍
T = R @ S                     # 先缩放后旋转

重要提示

  1. 使用@进行矩阵乘法,而不是*
  2. 检查矩阵是否可逆np.linalg.det(A) != 0
  3. 注意维度匹配:矩阵运算有严格的维度要求
  4. 处理奇异矩阵:使用np.linalg.pinv()求伪逆
  5. 性能优化:大矩阵运算考虑使用稀疏矩阵或分块计算

NumPy的线性代数模块非常强大,是机器学习、深度学习和科学计算的基础。