当前位置:首页>python>Python 零基础100天—Day72 NumPy 进阶

Python 零基础100天—Day72 NumPy 进阶

  • 2026-10-11 06:12:28
Python 零基础100天—Day72 NumPy 进阶

NumPy 进阶 — 矩阵、随机数与线性代数

🕐 预计用时:2-3 小时 | 🎯 目标:掌握矩阵运算、随机数生成、统计函数和线性代数操作


📖 今日目录

  1. 矩阵运算
  2. 随机数生成
  3. 统计函数
  4. 线性代数
  5. 数组变形与拼接
  6. 文件读写
  7. 性能优化技巧
  8. 今日练习
  9. 今日小结

1. 矩阵运算

import numpy as np# 矩阵乘法(线性代数中的乘法,不是逐元素)A = np.array([[1, 2],              [3, 4]])B = np.array([[5, 6],              [7, 8]])# 方法1:@ 运算符(推荐)C = A @ B# [[19 22]#  [43 50]]# 方法2:np.dot()C = np.dot(A, B)# 方法3:.dot() 方法C = A.dot(B)# 逐元素乘法(注意区分!)A * B# [[ 5 12]#  [21 32]]
运算
NumPy 写法
数学含义
逐元素乘
A * B
aij × bij
矩阵乘
A @ B
行 × 列,标准矩阵乘法
转置
A.T
行列互换
逆矩阵
np.linalg.inv(A)
A × A⁻¹ = I
行列式
np.linalg.det(A)
方阵的行列式值
# 矩阵的其他操作A = np.array([[1, 2], [3, 4]])np.linalg.inv(A)       # 逆矩阵np.linalg.det(A)       # 行列式 → -2.0np.trace(A)            # 迹(对角线之和)→ 5np.linalg.matrix_rank(A)  # 秩 → 2# 特征值与特征向量eigenvalues, eigenvectors = np.linalg.eig(A)print(eigenvalues)     # [-0.37  5.37]print(eigenvectors)

2. 随机数生成

import numpy as np# 设置随机种子(可复现)np.random.seed(42)# 均匀分布 [0, 1)np.random.random(5)           # 5 个 0-1 的随机数np.random.random((3, 3))      # 3x3 矩阵# 随机整数np.random.randint(1, 100, 5)         # 5 个 1-99 的随机整数np.random.randint(1, 100, (3, 4))    # 3x4 矩阵# 正态分布(高斯分布)np.random.randn(5)            # 标准正态分布(均值0,标准差1)np.random.randn(3, 3)         # 3x3 矩阵np.random.normal(100, 15, 5)  # 均值100,标准差15(模拟考试成绩)# 随机选择arr = np.array([10, 20, 30, 40, 50])np.random.choice(arr, 3)              # 从 arr 中随机选 3 个np.random.choice(arr, 3, replace=False)  # 不重复抽样np.random.choice(arr, (2, 3))         # 2x3 矩阵# 随机打乱deck = np.arange(52)np.random.shuffle(deck)     # 原地打乱(修改原数组)print(deck)# 随机排列(返回新数组)np.random.permutation(10)   # 0-9 的随机排列

💡 随机种子的重要性:np.random.seed(42) 设置种子后,每次运行生成的随机数相同——这对实验复现至关重要。在机器学习中,固定种子可以确保:每次训练结果一致,方便调试。

📌 NumPy 2.0+ 推荐写法:上面使用的 np.random.seed() 和 np.random.randn() 属于旧版 RandomState API,仍可使用但官方推荐改用新的 Generator API:rng = np.random.default_rng(42)rng.random(5)rng.normal(0, 1, 5)rng.integers(1, 100, 5)新 API 速度更快、分布更优,且每个 rng 对象独立管理种子,避免全局污染。

📋 常用分布

分布
函数
用途
均匀分布
np.random.uniform(a, b)
等概率取值
正态分布
np.random.normal(μ, σ)
身高、成绩等自然现象
二项分布
np.random.binomial(n, p)
n 次试验成功次数
泊松分布
np.random.poisson(λ)
稀有事件发生次数
指数分布
np.random.exponential(β)
等待时间

3. 统计函数

import numpy as npnp.random.seed(42)scores = np.random.normal(70, 15, (5, 3))  # 5 个学生,3 门课# 模拟成绩:均值70,标准差15# 基础统计np.mean(scores)                # 全体均值np.mean(scores, axis=0)        # 每门课的均值(按列)np.mean(scores, axis=1)        # 每个学生的均值(按行)np.median(scores)              # 中位数np.std(scores)                 # 标准差np.var(scores)                 # 方差np.ptp(scores)                 # 极差(最大值 - 最小值)# 分位数np.percentile(scores, 25)      # 第一四分位数(25%)np.percentile(scores, 50)      # 中位数(50%)np.percentile(scores, 75)      # 第三四分位数(75%)# 相关系数矩阵# 3 门课之间的相关性np.corrcoef(scores.T)          # 3x3 相关系数矩阵# 协方差矩阵np.cov(scores.T)               # 3x3 协方差矩阵# 直方图统计data = np.random.normal(0, 1, 1000)counts, bins = np.histogram(data, bins=10)print(f'区间: {bins}')print(f'频数: {counts}')

4. 线性代数

import numpy as npfrom numpy import linalg as LA# 解线性方程组# 2x + 3y = 8# 3x + 4y = 11A = np.array([[2, 3], [3, 4]])b = np.array([8, 11])x = LA.solve(A, b)print(x)  # [1. 2.] → x=1, y=2# 验证print(A @ x)  # [8. 11.] ✅# 向量范数(长度)v = np.array([3, 4])LA.norm(v)              # 5.0(L2范数,默认)LA.norm(v, 1)           # 7.0(L1范数,绝对值之和)LA.norm(v, np.inf)      # 4.0(无穷范数,最大绝对值)# 矩阵范数A = np.array([[1, 2], [3, 4]])LA.norm(A, 'fro')       # Frobenius 范数# 矩阵分解# SVD 分解(奇异值分解)U, S, Vt = LA.svd(A)print(f'U: {U.shape}, S: {S.shape}, Vt: {Vt.shape}')# QR 分解Q, R = LA.qr(A)# Cholesky 分解(正定矩阵)# LA.cholesky(A)  # A 必须是正定矩阵# 求解 Ax = b 的最小二乘解(超定方程组)A = np.array([[1, 1], [1, 2], [1, 3]])b = np.array([1, 2, 2.5])x, residuals, rank, sv = LA.lstsq(A, b, rcond=None)print(x)  # 最小二乘解

5. 数组变形与拼接

import numpy as np# === 变形 ===arr = np.arange(12)arr.reshape(3, 4)         # 3x4arr.reshape(4, 3)         # 4x3arr.reshape(2, -1)        # 2行,列自动算 → 2x6arr.reshape(-1, 6)        # 列6,行自动算 → 2x6arr.reshape(2, 3, 2)      # 三维 2x3x2# 展平arr2d = np.array([[1,2,3],[4,5,6]])arr2d.flatten()            # [1 2 3 4 5 6](返回副本)arr2d.ravel()              # [1 2 3 4 5 6](返回视图)arr2d.reshape(-1)          # [1 2 3 4 5 6](返回视图)# === 拼接 ===a = np.array([1, 2, 3])b = np.array([4, 5, 6])# 水平拼接(列方向)np.hstack([a, b])          # [1 2 3 4 5 6]np.concatenate([a, b])     # [1 2 3 4 5 6](同上)# 垂直拼接(行方向)np.vstack([a, b])# [[1 2 3]#  [4 5 6]]# 二维拼接A = np.array([[1, 2], [3, 4]])B = np.array([[5, 6], [7, 8]])np.concatenate([A, B], axis=0)  # 按行拼 → 4x2np.concatenate([A, B], axis=1)  # 按列拼 → 2x4# === 分割 ===arr = np.arange(12)np.split(arr, 3)          # 均分为3份 → [0,1,2,3], [4,5,6,7], [8,9,10,11]np.split(arr, [3, 7])     # 在索引3和7处分割 → [0,1,2], [3,4,5,6], [7,8,9,10,11]np.hsplit(arr2d, 3)       # 水平分割(列方向)np.vsplit(arr2d, 2)       # 垂直分割(行方向)

6. 文件读写

import numpy as np# === 二进制格式(推荐,速度快)===arr = np.array([[1, 2, 3], [4, 5, 6]])# 保存为 .npy 文件np.save('data.npy', arr)loaded = np.load('data.npy')# 保存多个数组为 .npz 文件np.savez('data.npz', a=arr, b=arr*2)data = np.load('data.npz')print(data['a'])print(data['b'])# === 文本格式(可读性好)===arr = np.array([[1, 2, 3], [4, 5, 6]])# 保存为文本np.savetxt('data.txt', arr, fmt='%d', delimiter=',')loaded = np.loadtxt('data.txt', delimiter=',')# 从 CSV 读取# np.genfromtxt('data.csv', delimiter=',', skip_header=1)

7. 性能优化技巧

import numpy as npimport time# 技巧1:避免 Python 循环,用向量化# ❌ 慢def slow_mean(arr):    total = 0    for x in arr:        total += x    return total / len(arr)# ✅ 快def fast_mean(arr):    return np.mean(arr)# 技巧2:预分配数组,避免动态增长# ❌ 慢(不断拼接新数组)result = np.array([])for i in range(1000):    result = np.append(result, i)  # 每次创建新数组!# ✅ 快(预分配)result = np.zeros(1000)for i in range(1000):    result[i] = i# 技巧3:用 np.where 替代条件循环# ❌ 慢result = []for x in arr:    if x > 0:        result.append(x)    else:        result.append(0)# ✅ 快result = np.where(arr > 0, arr, 0)# 技巧4:就地操作(避免创建副本)# ❌ 创建新数组arr = arr + 1# ✅ 就地修改arr += 1# 技巧5:用广播替代循环# ❌ 双重循环for i in range(n):    for j in range(m):        C[i,j] = A[i] * B[j]# ✅ 广播C = A[:, np.newaxis] * B[np.newaxis, :]

8. 今日练习

🏋️ 练习 1:矩阵运算

# 解方程组:# x + 2y + 3z = 1# 2x + 5y + 2z = 3# 6x - 3y +  z = 2# 用 LA.solve() 求解

🏋️ 练习 2:随机模拟

# 用 NumPy 模拟抛硬币实验:# 抛 1000 次,每次抛 10 个硬币# 统计正面朝上的次数分布# 画出直方图(用 np.histogram)

🏋️ 练习 3:图像处理

# 用 NumPy 模拟图像操作:# 创建一个 10x10 的灰度图矩阵(0-255)# 实现:亮度+50、对比度翻转、裁剪中心区域、水平翻转

9. 今日小结

知识点
核心内容
矩阵运算
A @ B 矩阵乘法 / .T 转置 / inv 求逆 / det 行列式
随机数
random / randint / randn / normal / choice / seed
统计函数
mean / std / median / percentile / corrcoef / histogram
线性代数
solve / norm / svd / qr / lstsq
变形拼接
reshape / flatten / hstack / vstack / concatenate / split
文件读写
save / load / savez / savetxt / loadtxt
性能优化
向量化 / 预分配 / np.where / 就地操作 / 广播

🚀 明日预告:Day 73 — Pandas 基础Series 和 DataFrame——数据分析师的 Excel 替代品。读取 CSV、查看数据、基础索引,数据科学的核心工具即将登场!

轻松时刻:

请在微信客户端打开

最新文章

随机文章