机器学习速成·前置(二):NumPy 上手——数组、随机数与广播
本文参考 Google ML Crash Course 前置工作 - NumPy UltraQuick Tutorial 撰写。这篇不是 NumPy 的完整教程,而是为了完成 MLCC 后续练习而够用的最小集。
一、NumPy 是什么?为什么机器学习用它?
NumPy(Numerical Python) 是 Python 里用于创建和操作矩阵的库——而矩阵正是机器学习算法使用的主要数据结构。
同一个东西在三个生态里有不同叫法:
| 生态 | 名称 |
|---|---|
| Python | 列表(list) |
| NumPy | 数组(array) |
| TensorFlow | 张量(tensor) |
它们本质上都是以行列方式存储数值的二维结构。有了 NumPy,你就能高效地存储、切片、运算一大批数值,这也是后续所有算法练习的基础。
二、导入模块
使用 NumPy 前,先导入它(惯例用别名 np):
import numpy as np
三、创建数组的四种方式
| 需求 | 函数 | 示例 |
|---|---|---|
| 指定数值 | np.array | np.array([1.2, 2.4, 3.5]) |
| 二维数组 | np.array(多加一层中括号) | np.array([[6, 5], [11, 7]]) |
| 全 0 | np.zeros | np.zeros(3) |
| 全 1 | np.ones | np.ones(3) |
| 整数序列 | np.arange | np.arange(5, 12) |
3.1 一维与二维
# 一维数组(8个元素)
one_dimensional_array = np.array([1.2, 2.4, 3.5, 4.7, 6.1, 7.2, 8.3, 9.5])
# 二维数组(3x2)
two_dimensional_array = np.array([[6, 5], [11, 7], [4, 8]])
3.2 序列生成:注意区间的”左闭右开”
sequence_of_integers = np.arange(5, 12)
# 结果:[5 6 7 8 9 10 11]
⚠️
np.arange生成的序列包含下界(5),但不包含上界(12)。 这是 NumPy 区间”左闭右开”最常见的坑。
四、生成随机数
NumPy 提供多种按范围生成随机数的函数:
4.1 随机整数:np.random.randint
# 在 50 ~ 100 之间生成 6 个随机整数
random_integers_between_50_and_100 = np.random.randint(low=50, high=101, size=(6,))
⚠️
np.random.randint生成的最大整数比high参数小 1。 想要覆盖 50~100,high要写 101。
4.2 随机浮点数:np.random.random
# 在 0.0 ~ 1.0 之间生成 6 个随机浮点数
random_floats_between_0_and_1 = np.random.random((6,))
五、数学运算与广播(Broadcasting)
数组之间做线性代数运算时,对维度兼容性有严格限制。好在 NumPy 用了一个叫 广播(Broadcasting) 的技巧:
广播:把一个维度较小的操作数”虚拟扩展”到能与另一个操作数匹配,从而对每个单元格做运算。
5.1 数组 + 标量(用广播给每个元素加 2.0)
random_floats_between_2_and_3 = random_floats_between_0_and_1 + 2.0
这里 2.0 是标量,广播会把它”虚扩展”成同维数组,然后一一对应相加——相当于给每个值都加 2.0。
5.2 数组 × 标量(用广播给每个元素乘 3)
random_integers_between_150_and_300 = random_integers_between_50_and_100 * 3
同理,给每个单元格都乘以 3。
关键点:广播是”隐式虚扩”,不真正复制数据,因此既安全又高效。它让你能用简洁直观的方式对整个数组做批量运算。
六、动手练习:做一个真实的小数据集
任务 1:创建线性数据集
目标是构建一个”单特征 + 标签”的简单数据集:
- 把 6 到 20(含 20) 的整数序列赋给数组
feature。 - 创建 15 个值的数组
label,满足label = (3)(feature) + 4。
例如第一个值:label = (3)(6) + 4 = 22。
解法思路——注意 np.arange(6, 21) 才能包含 6~20(上界 21 不包含):
feature = np.arange(6, 21) # [6 7 8 ... 20]
label = (feature * 3) + 4 # 广播:每个元素乘3再加4
任务 2:给数据集加上噪声
让数据集更真实些:给 label 的每个元素都加上一个**-2 到 +2** 之间的随机浮点数。
关键点:不要依赖广播,而是创建一个与 label 同维的 noise 数组:
noise = (np.random.random([15]) * 4) - 2
label = label + noise
说明:
np.random.random([15])生成 15 个 [0,1) 的浮点数;* 4让范围变成 [0,4);- 2整体平移得到 [-2,2);- 两个同维数组相加 → 逐元素相加,每个元素的噪声各不相同。
七、小结
| 需求 | 用哪个 | 易错点 |
|---|---|---|
| 指定数值 / 二维数组 | np.array | 二维加一层中括号 |
| 全 0 / 全 1 | np.zeros / np.ones | — |
| 整数序列 | np.arange(a, b) | 不含上界 b |
| 随机整数 | np.random.randint | 最大值为 high−1 |
| 随机浮点 | np.random.random(shape) | 范围 [0,1) |
| 批量运算 | 依赖广播 | 标量自动”虚扩”匹配维度 |
一句话:NumPy 就是对矩阵的”瑞士军刀”——
array造数据、arange/random快速生成、加减乘除靠广播批量搞定;而”左闭右开""high−1”这些小规则,正是用它少踩坑的关键。