3-3 NumPy数据的统计与广播

🎯 教学目标与重难点…

【三维目标】

  • 📚 知识目标:掌握常用统计函数(sum, mean, std)的使用;深刻理解 axis(轴)的计算方向规则;理解广播机制(Broadcasting)的自动补全拉伸原理。
  • ⚙️ 能力目标:能够正确运用 axis 参数完成二维数据集的按列/按行统计;能够使用 NumPy 纯代码实现机器学习中关键的数据预处理操作——Z-score 数据标准化($X_{\text{scaled}} = \frac{X - \mu}{\sigma}$)。
  • 💡 素养目标:建立“数据降维与特征压缩”的抽象逻辑,体会 NumPy 广播机制对代码精简与效率提升的巨大价值,提升数据预处理的工程实践素养。

【重点与难点】

  • 🟢 教学重点:统计函数中 axis(轴)的定向计算规则(axis=0 跨行按列求值,axis=1 跨列按行求值);广播机制的适用条件。
  • 🟡 教学难点:对 axis 维度的空间想象与“沿轴折叠,该维度消失”的理解;矩阵与向量广播相减时维度的自动对齐过程。

📌 一、 课程导入(10 分钟)

  1. 真实场景引入:不同量纲带来的“算法灾难”
    • 假设有一个二手房数据集,特征 1 为“房屋面积”(数值范围 50200 ㎡),特征 2 为“房间数”(数值范围 15 间)。
    • 提问:在计算两套房子之间的“相似度/距离”时,面积数值偏大(如差值 50)会完全掩盖房间数(如差值 2)的作用!
    • 解决办法:数据标准化(Z-score Normalization),把所有特征压缩到均值为 0、标准差为 1 的同一量纲下: $$X_{\text{scaled}} = \frac{X - \mu}{\sigma}$$

    • 思考:如何用两行代码算出每一列(每个特征)的均值 $\mu$ 与标准差 $\sigma$,并用整个矩阵去减它?
  • 👨‍🏫 教师活动:在黑板上呈现原始房屋数据集表格,引导学生发现“面积数值大、房间数数值小”导致不公平比较的问题,引出标准化的数学公式。
  • 🧑‍🎓 学生活动:观察数据形态,结合前面的切片知识,思考如果用循环实现该公式会有多繁琐。

通过机器学习特征缩放的真实痛点导入,让统计函数与广播机制不再是孤立的语法点,而是解决“数据标准化”这一核心任务的有力工具。


📖 二、 解决问题过程(一):定向统计与 axis 轴的奥秘(30 分钟)

  1. 常用统计函数
    • np.sum():求和
    • np.mean():求均值 $\mu$
    • np.std():求标准差 $\sigma$
  2. 核心攻克:axis(轴)的方向与口诀
    • 不指定 axis:对整张表格所有元素求全局统计值。
    • axis=0(按列统计/跨行折叠):沿着“纵向/行”的方向进行压缩,求出每个特征的统计值(如求每个特征的平均值,返回 $1 \times N$)。
    • axis=1(按行统计/跨列折叠):沿着“横向/列”的方向进行压缩,求出每个样本的统计值(如求每个学生的各科总分,返回 $M \times 1$)。
    • 💡 记忆口诀:“沿着哪个轴(axis)计算,哪个维度就被压缩折叠消失!”
  • 👨‍🏫 教师活动:在黑板上画出 $4 \times 3$ 的表格,手势演示沿 axis=0 纵向向下折叠压缩成一行,沿 axis=1 横向向右折叠压缩成一列。
  • 🧑‍🎓 学生活动:上机运行 np.mean(data, axis=0)axis=1,打印输出结果的 shape,对比验证口诀。

axis 是整个 NumPy 乃至深度学习中最易混淆的概念。用图形折叠与维度消失口诀替代抽象定义,彻底突破这一教学难点。


💻 三、 解决问题过程(二):广播机制与标准化实操(25 分钟)

  1. 广播机制(Broadcasting)的通俗理解
    • 当一个 $100 \times 3$ 的二维矩阵减去一个 $1 \times 3$ 的一维数组时,维度并不相同。
    • NumPy 的广播机制会自动将 $1 \times 3$ 的数组“沿着纵向向下复制拉伸 100 次”,变为 $100 \times 3$,然后再执行逐元素的相减操作!
  2. Z-score 数据标准化综合实战
 1import numpy as np
 2
 3# 1. 模拟真实房屋数据集 (5个样本,3个特征:[面积, 房间数, 车库数])
 4X = np.array([
 5    [85.0,  2.0, 1.0],
 6    [120.0, 3.0, 2.0],
 7    [60.0,  1.0, 0.0],
 8    [150.0, 4.0, 1.0],
 9    [95.0,  2.0, 1.0]
10])
11
12print("--- 原始数据 X ---")
13print(X)
14
15# 2. 按列计算各个特征的均值与标准差 (axis=0 代表跨行按列)
16mean = np.mean(X, axis=0)  # shape 为 (3,)
17std = np.std(X, axis=0)    # shape 为 (3,)
18
19print("\n各个特征的均值 mu:", mean)
20print("各个特征的标准差 sigma:", std)
21
22# 3. 运用广播机制完成标准化: (X - mean) / std
23# 这里的 mean 和 std 会被自动纵向广播扩充匹配 X 的 (5, 3) 形状
24X_scaled = (X - mean) / std
25
26print("\n--- 标准化后的数据 X_scaled ---")
27print(X_scaled)
28
29# 4. 验证标准化结果: 新数据的均值应接近 0,标准差应接近 1
30print("\n验证标准化后各特征均值 (应接近0):", np.mean(X_scaled, axis=0).round(4))
31print("验证标准化后各特征标准差 (应为1):", np.std(X_scaled, axis=0).round(4))
  • 👨‍🏫 教师活动:分步运行标准化代码,重点展示 (X - mean) 这一步中不同 shape 数组相减的过程,解释广播机制的自动补全。
  • 🧑‍🎓 学生活动:敲击代码完成标准化练习,观察输出的 X_scaled 中各特征数值被缩放到统一量纲下的变化。

将抽象的广播机制与现实的数据标准化公式结合,让学生在完成完整实战的过程中自然消化广播的自动拉伸特性。


✍️ 四、 解决问题过程(三):课堂练习与巩固(20 分钟)

📝 任务一:学生成绩单汇总与中心化预处理…

背景与题目: 某班级 4 名同学的 3 门课程(语文、数学、英语)成绩如下表所示。请根据给出的 NumPy 数组,完成以下操作:

  1. 成绩汇总:计算每位同学的 3 门课程总分,赋值给 student_sums
  2. 单科均值:计算全班每门课程的平均分,赋值给 subject_means
  3. 数据中心化(Zero-Centered):使用广播机制,将整张成绩单减去各自单科的平均分(即 $X - \text{subject\_means}$),使各科均值变为 0。
1import numpy as np
2
3# 4名学生的 3科成绩
4scores = np.array([
5    [80, 95, 88],
6    [70, 65, 72],
7    [90, 90, 94],
8    [60, 85, 78]
9])
🔍 查看参考代码与解析…
 1# 1. 计算每位同学的 3 门课程总分 (跨列按行求和 -> axis=1)
 2student_sums = np.sum(scores, axis=1)
 3print("每位同学的总分:\n", student_sums)
 4
 5# 2. 计算全班每门课程的平均分 (跨行按列求均值 -> axis=0)
 6subject_means = np.mean(scores, axis=0)
 7print("\n每门课程的平均分:\n", subject_means)
 8
 9# 3. 数据中心化 (利用广播机制: (4, 3) 矩阵 减去 (3,) 向量)
10scores_centered = scores - subject_means
11print("\n中心化后的成绩单 (每科均值变0):\n", scores_centered)
12
13# 验证中心化后的单科均值
14print("\n验证中心化后各科均值:", np.mean(scores_centered, axis=0))

【解析】

  • 统计“每位同学”的总分,是横向合并列维度,因此使用 axis=1
  • 统计“每门课程”的平均分,是纵向合并行维度,因此使用 axis=0
  • scores - subject_means 中,(3,) 维度的平均分数组沿 axis=0(纵向)广播延伸成 (4, 3) 进行逐元素相减。

📝 五、 课堂小结(5 分钟)

flowchart LR
    root["📊 2-3 NumPy 基础:数据的统计与广播"]

    subgraph C1["📐 统计函数与 axis 轴"]
        direction TB
        A1["基础函数:sum, mean, std"]
        A2["axis=0:跨行按列 (求特征指标)"]
        A3["axis=1:跨列按行 (求样本指标)"]
        A4["口诀:沿哪个轴算,哪个维度消失"]
    end

    subgraph C2["📡 广播机制 (Broadcasting)"]
        direction TB
        B1["触发条件:维度不相同但兼容"]
        B2["核心动作:自动沿缺失轴拉伸复制"]
        B3["优势:无需写 for 循环逐项计算"]
    end

    subgraph C3["🚀 预处理实战"]
        direction TB
        C1_node["Z-score 标准化公式:(X - mean) / std"]
        C2_node["目的:统一不同特征的量纲"]
    end

    root --> C1
    root --> C2
    root --> C3

    %% 自定义主题色彩美化
    style root fill:#4b6cb7,stroke:#253b6e,color:#fff,stroke-width:2px,rx:8px,ry:8px
    style C1 fill:#e3f2fd,stroke:#2196f3,stroke-width:1px
    style C2 fill:#fff3e0,stroke:#ff9800,stroke-width:1px
    style C3 fill:#e8f5e9,stroke:#4caf50,stroke-width:1px

✏️ 随堂检测与互动练习

点击展开:随堂测试题(带解析)

一、 单选题

  1. 对于一个形状为 (10, 5) 的二维数据集 data(代表 10 个样本,5 个特征),如果想要计算每个特征(每列)的标准差,正确的代码是?
  • A. np.std(data)
  • B. np.std(data, axis=0)
  • C. np.std(data, axis=1)
  • D. np.std(data, axis=-1)
【答案】

【解析】B。对特征(列)进行统计需要跨行纵向计算,对应的轴是 axis=0,计算后返回形状为 (5,) 的数组。

  1. 下列关于 NumPy 广播机制(Broadcasting)的说法,错误的是?
  • A. 广播机制使得不同形状的数组可以在某些算术运算中相加减
  • B. 形状为 (3, 4) 的矩阵和形状为 (4,) 的一维数组可以进行加法运算
  • C. 广播机制是在内存中复制了多份数据后再运算,因此非常消耗内存空间
  • D. 广播机制可以让我们摆脱显式的 Python for 循环
【答案】

【解析】C。NumPy 在执行广播时,并不会真正去复制内存数据,而是巧妙地调整指针步长(Strides),因此既节省内存,速度又极快。

二、 代码填空题

题目:请补充以下计算 Z-score 标准化 的代码,使矩阵 X 按照特征列完成标准化:

 1import numpy as np
 2
 3X = np.array([[10, 200], [20, 400], [30, 600]])
 4
 5# 1. 计算每一列的均值
 6m = np.mean(X, axis=_______)
 7
 8# 2. 计算每一列的标准差
 9s = np.std(X, axis=_______)
10
11# 3. 计算标准化矩阵
12X_norm = (X - m) / _______
【答案】
  1. 0
  2. 0
  3. s

三、 思考与简答题

题目:假设 A 的形状是 (3, 3)B 的形状是 (3,),解释执行 A + B 时广播机制是如何工作的?

【答案】
  1. B 的形状是 (3,),在与二维矩阵 A 进行运算时,先自动将维度补全为 (1, 3)
  2. NumPy 发现 A 有 3 行,而 B 只有 1 行,于是沿 axis=0(纵向)将 B 视作拉伸复制了 3 次,使其虚拟形状扩展为 (3, 3)
  3. 最终 A 和拉伸后的 B 按照对应位置(Element-wise)逐元素相加。

📮 六、 课后作业与拓展

📮 课后作业…
  1. 基础统计:创建一个 $5 \times 5$ 的随机整数矩阵,分别计算:整个矩阵的最小值、每一行的最大值、每一列的平均值。
  2. Min-Max 归一化实操:除了 Z-score,另一种常见的预处理是 Min-Max 归一化,公式为:
$$X_{\text{norm}} = \frac{X - X_{\text{min}}}{X_{\text{max}} - X_{\text{min}}}$$

请用纯 NumPy 代码实现该公式,将一个 $4 \times 3$ 的矩阵压缩到 $[0, 1]$ 区间内。 3. 广播机制探究:尝试运行 np.ones((3, 4)) + np.ones((3, 1)) 以及 np.ones((3, 4)) + np.ones((2, 4)),观察哪一个会报错?思考为什么? 4. 单元复习大作业(准备):结合前三次课内容,总结 NumPy 中分离特征与标签、改变数据形态、特征标准化的完整代码流程,绘制一份 NumPy 知识思维导图。


📋 七、 板书设计

🛠️ 板书设计…
 12-3 NumPy 基础:数据的统计与广播
 2
 3一、 定向统计与 axis 轴 (核心重点!)
 4  - 常用函数: np.sum() / np.mean() / np.std()
 5  
 6  - axis 轴的含义:
 7    * axis=0 : 跨行按列求值   --> 求特征均值 (列数不变,行数压缩)
 8    * axis=1 : 跨列按行求值   --> 求样本总分 (行数不变,列数压缩)
 9  
10  - 口诀: 沿哪个轴计算,哪个维度就折叠消失!
11
12二、 广播机制 (Broadcasting)
13  - 现象: (5, 3) 矩阵  -  (3,) 向量  --> 自动匹配计算
14  - 过程: 自动将 (3,) 虚拟扩充为 (5, 3) 纵向拉伸
15
16三、 Z-score 数据标准化实战
17  公式:  X_scaled = (X - mean) / std
18  代码:  mean = np.mean(X, axis=0)
19         std  = np.std(X, axis=0)
20         X_norm = (X - mean) / std