3-2 NumPy数据的变形与定位

🎯 教学目标与重难点…

【三维目标】

  • 📚 知识目标:理解 shape 属性含义;掌握 reshape 形态变换规则及 -1 的特殊用法;掌握 argmaxargmin 在维度定位中的作用。
  • ⚙️ 能力目标:能够灵活运用 reshape 调整特征数据的维度(如单特征矩阵转换与图像展平);能够利用 argmax 获取分类模型概率输出的最大索引。
  • 💡 素养目标:建立严谨的“维度匹配”观念,提升解决实际机器学习报错(如维度不匹配)的调试能力与逻辑思维能力。

【重点与难点】

  • 🟢 教学重点shape 属性与 reshape() 改变数组形态;-1 自动推导维度的用法;argmax() 获取最大值索引。
  • 🟡 教学难点:理解 reshape(-1, 1) 将一维数组转换为二维列向量的场景与必要性;flatten()ravel() 的展平机制。

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

  1. 复习抽测(5分钟)
    • 提问:如何从 $100 \times 4$ 的数据集 data 中切片提取出特征集 $X$ 和标签 $y$?
    • 学生回答:X = data[:, :-1]y = data[:, -1]
  2. 场景引入:遇到机器学习常见的“维度报错”
    • 场景 1:图片是 $28 \times 28$ 的二维方格,但神经网络模型只接受一维的 784 个像素特征值。
    • 场景 2:使用单特征预测房价(只有一个特征“面积”),把一维数组 [85, 120, 60] 直接传给 scikit-learn 算法模型时,系统抛出报错:Expected 2D array, got 1D array instead
    • 引入课题:如何自由操控数据的“形态”,以及如何在多维度中“精准定位”?
  • 👨‍🏫 教师活动:在 Jupyter 中演示将一维数组传给算法库时的报错提示,让学生看懂 Expected 2D array 的关键信息。
  • 🧑‍🎓 学生活动:观察报错日志,体会“数据总数没变,但数据形态不对”引发的问题,产生解决问题的需求。

以真实报错作为问题驱动,避免枯燥的语法讲解,直接将“形态变换”与机器学习算法的强依赖性绑定,提升学习针对性。


📖 二、 解决问题过程(一):数据的“变形术” reshape(30 分钟)

  1. 查看形状 shape 属性
    • arr.shape 返回元组,代表各维度的大小。例如 (100, 4) 表示 100 行 4 列。
  2. 形态变换 reshape() 核心法则
    • 守恒定律:变换前后,数组的元素总个数必须保持一致!(如 12 个元素可转为 $3\times 4$、$4\times 3$、$2\times 6$,但不能转为 $3\times 5$)。
  3. 关键技巧:-1 自动推导维度
    • 告诉 NumPy:“其中某一维我懒得算,由你根据总数自动计算”。
    • 示例:12 个元素,arr.reshape(3, -1) $\rightarrow$ NumPy 自动推导列数为 4。
  4. 避坑必会:reshape(-1, 1) 与 展平 (flatten)
    • reshape(-1, 1):把一维行向量(shape: (N,))转换为二维列向量(shape: (N, 1)),专门解决算法库的“2D 期望报错”。
    • flatten() / ravel():将多维数据拉直为一维数组(如把 $28 \times 28$ 图像拉直为 784 维向量)。
  • 👨‍🏫 教师活动:用积木比喻解释数据排列:12 块积木摆成一条线(1D)或摆成 3 行 4 列(2D),总量不变。现场演示 -1 参数的推导过程。
  • 🧑‍🎓 学生活动:在 Jupyter 中敲击 reshape 代码,故意输入无法整除的形状(如将 12 个元素 reshape(3, 5))观察报错信息,加深“元素守恒”印象。

突破 -1 自动计算的理解难点,帮助学生彻底搞懂一维 (N,) 与二维列向量 (N, 1) 的形态差异,打通后续 machine learning 模型调包的障碍。


💻 三、 解决问题过程(二):数据的“定位器” argmax(25 分钟)

  1. 寻找最大/最小值与定位索引的区别
    • np.max():告诉我最大值是多少
    • np.argmax():告诉我最大值所在的位置(下标/索引)
  2. 机器学习真实场景应用
    • 在图像分类模型(如手写数字识别 0~9)中,模型的输出通常是概率数组。例如:[0.05, 0.10, 0.80, 0.02, 0.03]
    • 我们不在乎最高概率是 0.80,而是在乎 0.80 所在的索引位置是 2,这意味着模型预测该图片是“数字 2”。
 1import numpy as np
 2
 3# 1. 模拟单特征数据转换场景:房屋面积特征(1维 -> 2维列向量)
 4area = np.array([85, 120, 60, 150, 95])
 5print("原始面积维度 shape:", area.shape)  # 输出: (5,)
 6
 7# 使用 reshape(-1, 1) 转为 2D 矩阵以符合算法库要求
 8X_single_feature = area.reshape(-1, 1)
 9print("转换后面积维度 shape:\n", X_single_feature.shape)  # 输出: (5, 1)
10print("转换后的 2D 列向量:\n", X_single_feature)
11
12print("-" * 40)
13
14# 2. 模拟分类模型预测结果定位场景
15# 假设模型输出了一张动物图片属于 [猫, 狗, 兔] 的概率预测
16predict_probs = np.array([0.12, 0.75, 0.13])
17classes = ["猫", "狗", "兔"]
18
19# 使用 argmax 获取概率最大的类别索引
20max_index = np.argmax(predict_probs)
21predicted_class = classes[max_index]
22
23print(f"最大概率值: {np.max(predict_probs)}")
24print(f"最大概率对应的索引位置: {max_index}")
25print(f"模型最终预测结果: {predicted_class}")
  • 👨‍🏫 教师活动:演示 argmax 的推导过程,说明分类决策逻辑,引导学生理解“为什么索引就是类别 ID”。
  • 🧑‍🎓 学生活动:编写代码,尝试更改预测概率数组中的数值,观察 argmax 索引变化及对应预测类别的改变。

argmax 与分类算法预测逻辑打通,让学生理解“求索引”在 AI 判定中的实际应用,避免枯燥的函数说明。


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

📝 任务一:图像特征展平与分类预测结果提取…

背景与题目: 你正在开发一款智能门禁系统的分类模块,获得了以下两份数据需要处理:

  1. 图像处理:门禁摄像头摄入了一张 $3 \times 3$ 像素的低分辨率人脸灰度图 face_img,请使用代码将其展平(Flatten)为一维特征数组,以便输入模型。
  2. 分类预测:人脸识别模型针对某张输入图片,输出属于 4 个不同人名 ['张三', '李四', '王五', '赵六'] 的概率分布数组 probs,请使用代码找出概率最高的人名。
 1import numpy as np
 2
 3# 1. 原始 3x3 图像矩阵
 4face_img = np.array([
 5    [10, 25, 30],
 6    [45, 90, 80],
 7    [50, 60, 20]
 8])
 9
10# 2. 模型输出的 4 个类别的预测概率
11probs = np.array([0.08, 0.65, 0.20, 0.07])
12names = ['张三', '李四', '王五', '赵六']
🔍 查看参考代码与解析…
 1# 1. 展平图像矩阵为 1维 特征数组
 2flatten_face = face_img.flatten()  # 或 face_img.reshape(-1)
 3print("展平后的图像特征向量:\n", flatten_face)
 4print("展平后的 shape:", flatten_face.shape)
 5
 6print("\n" + "="*30 + "\n")
 7
 8# 2. 获取概率最大值索引并匹配姓名
 9top_index = np.argmax(probs)
10top_name = names[top_index]
11print(f"预测最高概率: {probs[top_index]:.2f}")
12print(f"系统识别出的人员为: {top_name}")

【解析】

  • 将 $3 \times 3$ 矩阵拉直为一维可使用 .flatten().ravel().reshape(-1)
  • np.argmax(probs) 返回数组中最大元素 0.65 的索引位置 1,对应列表 names[1] 即为 '李四'

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

flowchart LR
    root["📊 2-2 NumPy 基础:数据的变形与定位"]

    subgraph C1["📐 维度查看与规则"]
        direction TB
        A1["arr.shape:获取维度元组"]
        A2["守恒定律:变形前后元素总数不变"]
    end

    subgraph C2["🔄 形态变换 (reshape)"]
        direction TB
        B1["reshape(行, 列):重组数据维度"]
        B2["-1 参数:自动推导未知维度"]
        B3["reshape(-1, 1):转二维列向量 (避坑)"]
        B4["flatten():多维矩阵拉直为一维"]
    end

    subgraph C3["🎯 维度定位 (argmax)"]
        direction TB
        C1_node["np.max():获取最大数值"]
        C2_node["np.argmax():获取最大值索引"]
        C3_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. 已知一个 NumPy 数组 arrshape(24,),执行 arr.reshape(4, -1) 后,新数组的 shape 是?
  • A. (4, 4)
  • B. (4, 6)
  • C. (6, 4)
  • D. (4, 24)
【答案】

【解析】B。元素总数为 24,指定行数为 4,则列数根据守恒定律自动推导为 $24 \div 4 = 6$,因此形状为 (4, 6)

  1. 在手写数字识别分类任务中,已知神经网络输出概率数组为 output = np.array([0.01, 0.05, 0.02, 0.85, 0.07]),执行 np.argmax(output) 的返回值是?
  • A. 0.85
  • B. 3
  • C. 4
  • D. (3,)
【答案】

【解析】B。数组中最大值是 0.85,其所在的索引下标为 3(从 0 开始计数:0, 1, 2, 3)。

二、 代码填空题

题目:为了把包含 100 个样本的特征数组 x(原始形态为一维 (100,))转换为线性回归算法要求的二维列向量 (100, 1),请补充代码:

1import numpy as np
2
3x = np.arange(100)  # shape 为 (100,)
4
5# 将 x 转为二维列向量 (100, 1)
6X_2d = x._____________________
【答案】

reshape(-1, 1)(或 reshape(100, 1)

三、 思考与简答题

题目:在 NumPy 中,arr.reshape(2, 3) 操作会改变原数组 arr 本身的数据形态吗?

【答案】

不会reshape() 函数不会直接修改原数组,而是返回一个新的重组了形态的视图(View)或副本。如果需要持久保存修改后的形态,必须将其重新赋值给新变量(如 new_arr = arr.reshape(2, 3))或覆盖原变量。

📮 六、 课后作业与拓展

📮 课后作业…
  1. 维度变换实操:创建一个包含 1 至 16 的一维数组,分别写代码将其转换为:
  • $4 \times 4$ 的二维矩阵;
  • $2 \times 8$ 的二维矩阵;
  • $16 \times 1$ 的二维列向量。
  1. 极值与索引:创建一个 $3 \times 4$ 的随机数矩阵,尝试查找全局最大值及其所在的一维展平索引。
  2. 图像尺寸拉直:假设有一批 MNIST 手写数字图片数据集,形状为 (100, 28, 28)(代表 100 张 $28 \times 28$ 的灰度图片),请写出一行代码,将其批量展平为 (100, 784) 的二维特征矩阵。
  3. 扩展预习:预习 2.3 节,思考:如果一个 $3 \times 3$ 的矩阵要和一个 $1 \times 3$ 的数组相加,维度并不完全相同,NumPy 会报错还是会自动处理?

📋 七、 板书设计

🛠️ 板书设计…
 12-2 NumPy 基础:数据的变形与定位
 2
 3一、 维度查看与变形守恒
 4  - 查看维度: arr.shape
 5  - 核心原则: 元素总数变 (总量不变)
 6  - 语法: arr.reshape(行数, 列数)
 7
 8二、 高频实用变形技巧
 9  - -1 自动推导: arr.reshape(3, -1)
10  - 单特征转列向量: arr.reshape(-1, 1)   (解决 2D Array 报错!)
11  - 展平一维: arr.flatten()
12
13三、 定位函数 argmax vs max
14  - np.max(arr)    --> 找“最大值是多少” (数值)
15  - np.argmax(arr) --> 找“最大值在哪”   (索引/分类类别ID)