视频链接
https://www.bilibili.com/video/BV1CnFdzjEo9/
NumPy 速成教程(具体函数名不用记,用的时候查文档即可)
目标:快速掌握 NumPy 数组操作的核心用法
前夕、数组以及数组的维度
在正式学习 NumPy 之前,我们先来理解一个核心概念:数组。
Python数组的概念
在 Python 中,数组(Array) 和 列表(List) 是两个容易混淆的概念。让我们先理清它们的区别:
| 特性 | Python 列表 (List) | Python 数组 (Array) |
|---|---|---|
| 导入方式 | 内置,无需导入 | import array |
| 数据类型 | 可以混合存放任意类型 | 同一数组只能存放一种类型 |
| 存储效率 | 较低(存储对象引用) | 较高(紧凑存储) |
| 数学运算 | 不支持直接进行数组运算 | 支持基础运算 |
| 使用场景 | 通用数据集合 | 大量同类型数值数据 |
# Python 列表示例 - 可以存放任意类型
my_list = [1, "hello", 3.14, True] # 混合类型,完全合法
# Python array 示例 - 必须指定类型码
import array
my_array = array.array('i', [1, 2, 3, 4, 5]) # 'i' 表示整数
# NumPy 数组示例 - 最常用
import numpy as np
my_numpy_array = np.array([1, 2, 3, 4, 5])
💡 核心区别:
- 列表是 Python 的"万能容器",什么都能装,但效率较低
- 数组要求所有元素类型一致,存储更紧凑,运算更高效
- NumPy 数组是科学计算的事实标准,功能最强大
⚠️ 重要提示:在实际开发中,Python 原生的
array模块已经很少被直接使用。原因是 NumPy 提供了更强大、更高效的数组操作功能,完全覆盖了原生数组的使用场景。因此:
- 如果你需要处理数值数据 → 使用 NumPy 数组
- 如果你只是存储混合类型的数据 → 使用 Python 列表
- Python 原生的
array模块仅在极少数特殊场景下才会考虑(如对内存有极致要求且不能安装 NumPy 的环境)
🎯 一维数组:像排队一样简单
想象一下,学校食堂打饭时,同学们排成一条长队:
小明 → 小红 → 小刚 → 小丽 → 小华
0 1 2 3 4
这就是一维数组——只需要一个数字(位置/索引)就能找到任何人。
# 一维数组:Python 列表
queue = ["小明", "小红", "小刚", "小丽", "小华"]
print(queue[0]) # 小明 ← 第1个人(索引0)
print(queue[2]) # 小刚 ← 第3个人(索引2)
生活中的例子:
- 一周7天的温度记录
[22, 25, 28, 30, 29, 26, 24] - 一个班级10个学生的身高
[165, 170, 168, 172, ...] - 一年12个月的销售额
[100, 120, 110, 130, ...]
🎯 二维数组:像教室座位一样直观
现在,想象一间教室的座位安排:
第0列 第1列 第2列 第3列
第0行 小明 小红 小刚 小丽
第1行 小华 小强 小美 小亮
第2行 小军 小芳 小伟 小敏
这就是二维数组——需要两个数字(行号和列号)才能确定一个位置。
💡 二维数组的本质
二维数组其实就是"列表的列表"——一个列表里,每个元素又是一个列表!
# 二维数组:列表的列表
classroom = [
["小明", "小红", "小刚", "小丽"], # 第0行(是一个列表)
["小华", "小强", "小美", "小亮"], # 第1行(是一个列表)
["小军", "小芳", "小伟", "小敏"] # 第2行(是一个列表)
]
# 访问方式:先取行,再取列
print(classroom[0]) # ["小明", "小红", "小刚", "小丽"] ← 第0行
print(classroom[0][1]) # 小红 ← 第0行的第1个元素
print(classroom[2][3]) # 小敏 ← 第2行的第3个元素
🔍 可视化理解:二维数组的索引访问
classroom 数组结构:
第0列 第1列 第2列 第3列
┌─────────┬─────────┬─────────┬─────────┐
第0行 │ 小明 │ 小红 │ 小刚 │ 小丽 │ ← classroom[0]
├─────────┼─────────┼─────────┼─────────┤
第1行 │ 小华 │ 小强 │ 小美 │ 小亮 │ ← classroom[1]
├─────────┼─────────┼─────────┼─────────┤
第2行 │ 小军 │ 小芳 │ 小伟 │ 小敏 │ ← classroom[2]
└─────────┴─────────┴─────────┴─────────┘
↑
classroom[2][3]
索引访问过程:
┌─────────────────┐ ┌─────────────────┐ ┌─────────┐
│ classroom[2] │ ──→ │ 第2行子列表 │ ──→ │ 小敏 │
│ │ │ ["小军","小芳", │ │ │
│ 先取第2行 │ │ "小伟","小敏"] │ │ 最终结果│
└─────────────────┘ └─────────────────┘ └─────────┘
↓
[3] 再取第3个元素
详细对应关系:
| 代码 | 访问路径 | 结果 |
|---|---|---|
classroom[0] |
第0行 | ["小明", "小红", "小刚", "小丽"] |
classroom[0][1] |
第0行 → 第1列 | 小红 |
classroom[2][3] |
第2行 → 第3列 | 小敏 |
classroom[1][2] |
第1行 → 第2列 | 小美 |
看明白了吗?
classroom是一个列表,里面有3个元素- 每个元素(如
classroom[0])又是一个列表,里面有4个名字 - 所以
classroom[0][1]就是:先拿到第0行,再拿这一行的第1个元素
生活中的例子:
- 学生成绩单:行是学生,列是科目
- 电子表格:Excel 表格就是二维数组
- 图片:像素点的行和列
- 电影院座位:第几排第几座
🔄 一维 vs 二维 对比
| 特性 | 一维数组 | 二维数组 |
|---|---|---|
| Python表示 | [a, b, c, d] |
[[a, b], [c, d]] |
| 本质 | 一个列表 | 列表的列表(元素是一维数组) |
| 索引 | 1个数字 list[i] |
2个数字 list[i][j] |
| 形象比喻 | 排队、一串糖葫芦 | 教室座位、棋盘、Excel表 |
| 适用场景 | 时间序列、单一数据列表 | 表格数据、矩阵运算、图像 |
💡 重要提示
- 索引从0开始:这是编程的惯例,第1个元素的索引是0
- 先取行,再取列:
array[i][j],就像先说第几排,再说第几座 - 二维的本质:二维数组 = 一维数组里装的元素还是一维数组
现在你已经理解了数组的维度概念,让我们正式开始 NumPy 的学习之旅!
一、NumPy 基础
1.1 核心知识点
NumPy 是 Python 科学计算的基础库,核心是多维数组对象 ndarray。
import numpy as np
# 从列表创建数组
arr1 = np.array([1, 2, 3, 4, 5])
# 创建二维数组(矩阵)
arr2 = np.array([[1, 2, 3], [4, 5, 6]])
# 查看数组属性
print(arr2.shape) # (2, 3) - 2行3列
print(arr2.ndim) # 2 - 二维
print(arr2.size) # 6 - 元素总数
print(arr2.dtype) # int64 - 数据类型
🔍 可视化理解:一维数组 vs 二维数组
一维数组(1D Array):
一维数组就像一排储物柜:
索引: [0] [1] [2] [3] [4]
┌─────┐┌─────┐┌─────┐┌─────┐┌─────┐
│ 10 ││ 20 ││ 30 ││ 40 ││ 50 │
└─────┘└─────┘└─────┘└─────┘└─────┘
代码: arr1 = np.array([10, 20, 30, 40, 50])
arr1[0] → 10 (第1个元素)
arr1[2] → 30 (第3个元素)
arr1.shape → (5,) (5个元素)
arr1.ndim → 1 (1维)
二维数组(2D Array):
二维数组就像一个教室的座位表:
第0列 第1列 第2列
┌─────┐┌─────┐┌─────┐
第0行 │ 1 ││ 2 ││ 3 │
├─────┼┼─────┼┼─────┤
第1行 │ 4 ││ 5 ││ 6 │
└─────┘└─────┘└─────┘
代码: arr2 = np.array([[1, 2, 3],
[4, 5, 6]])
访问元素需要两个索引 [行, 列]:
arr2[0, 0] → 1 (第0行第0列)
arr2[0, 2] → 3 (第0行第2列)
arr2[1, 1] → 5 (第1行第1列)
arr2[1, 2] → 6 (第1行第2列)
属性:
arr2.shape → (2, 3) (2行3列)
arr2.ndim → 2 (2维)
arr2.size → 6 (共6个元素)
对比总结:
| 特性 | 一维数组 | 二维数组 |
|---|---|---|
| 形象比喻 | 一排储物柜 | 教室座位表 |
| 索引方式 | [i] |
[行, 列] 或 [i][j] |
| shape | (n,) |
(行数, 列数) |
| ndim | 1 | 2 |
| 创建方式 | [1, 2, 3] |
[[1, 2], [3, 4]] |
常用创建函数:
| 函数 | 示例 | 说明 |
|---|---|---|
np.zeros() |
np.zeros((3, 3)) |
创建全0数组 |
np.ones() |
np.ones((2, 4)) |
创建全1数组 |
np.arange() |
np.arange(5) / np.arange(0, 5) / np.arange(0, 10, 2) |
等差数列 [0,1,2,3,4] / [0,1,2,3,4] / [0,2,4,6,8] |
np.linspace() |
np.linspace(0, 1, 5) |
等间隔5个数 [0, 0.25, 0.5, 0.75, 1] |
np.random.rand() |
np.random.rand(3, 3) |
0-1随机数 |
💡 提示:
np.arange()与 Python 原生range()用法相似,但返回值类型不同:
np.arange(5)返回 NumPy 数组[0 1 2 3 4],range(5)返回 range 对象(需用list(range(5))才能查看内容[0, 1, 2, 3, 4])np.arange(0, 5)返回 NumPy 数组[0 1 2 3 4],range(0, 5)返回 range 对象np.arange(0, 10, 2)返回 NumPy 数组[0 2 4 6 8],range(0, 10, 2)返回 range 对象区别总结:
np.arange()直接返回 NumPy 数组(numpy.ndarray)range()返回 range 对象(可迭代对象,需转换为 list 才能查看内容)📚 温故知新:
range结合for循环的用法# range 常用于 for 循环中 for i in range(5): print(i) # 输出: 0, 1, 2, 3, 4 # 带起始值和步长 for i in range(0, 10, 2): print(i) # 输出: 0, 2, 4, 6, 8 # np.arange 同样可以用于 for 循环 for i in np.arange(5): print(i) # 输出: 0, 1, 2, 3, 4
1.2 练习题
练习1-1:补全代码,创建 NumPy 数组
import numpy as np
# TODO: 创建一个包含 [10, 20, 30, 40, 50] 的一维数组,赋值给 arr1
arr1 = __________
print(f"arr1: {arr1}")
# 预期输出: arr1: [10 20 30 40 50]
# TODO: 创建一个 3x3 的全0数组,赋值给 zeros_arr
zeros_arr = __________
print(f"zeros_arr:\n{zeros_arr}")
# 预期输出:
# zeros_arr:
# [[0. 0. 0.]
# [0. 0. 0.]
# [0. 0. 0.]]
# TODO: 创建 0 到 20(不含20),步长为 4 的数组,赋值给 range_arr
range_arr = __________
print(f"range_arr: {range_arr}")
# 预期输出: range_arr: [ 0 4 8 12 16]
# TODO: 创建 0 到 1 之间等间隔的 5 个数,赋值给 lin_arr
lin_arr = __________
print(f"lin_arr: {lin_arr}")
# 预期输出: lin_arr: [0. 0.25 0.5 0.75 1. ]
# TODO: 创建一个 2x3 的随机数组(0-1之间),赋值给 rand_arr
rand_arr = __________
print(f"rand_arr:\n{rand_arr}")
# 预期输出: (2行3列的随机数,每次运行结果不同)
二、数组索引与切片
2.1 核心知识点
import numpy as np
arr = np.array([[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]])
# 索引访问
print(arr[0, 1]) # 2 - 第0行第1列
print(arr[1, :]) # [5, 6, 7, 8] - 第1行
print(arr[:, 2]) # [3, 7, 11] - 第2列
print(arr[0:2, 1:3]) # [[2, 3], [6, 7]] - 子矩阵
索引方式:
| 操作 | 示例 | 说明 |
|---|---|---|
| 单个元素 | arr[1, 2] |
第1行第2列 |
| 某一行 | arr[0, :] |
第0行所有列 |
| 某一列 | arr[:, 1] |
所有行第1列 |
| 子矩阵 | arr[0:2, 0:2] |
前2行前2列 |
| 布尔索引 | arr[arr > 5] |
所有大于5的元素 |
🔍 深入理解:NumPy 布尔索引的工作原理
第一步:arr > 5 返回什么?
import numpy as np
arr = np.array([[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]])
# 看看 arr > 5 返回什么
condition = arr > 5
print(condition)
print(type(condition))
print(condition.dtype)
输出:
[[False False False False]
[False True True True]
[ True True True True]]
<class 'numpy.ndarray'>
bool
解释:
arr > 5返回一个与原数组形状相同的布尔数组- 每个元素对应原数组相同位置的元素是否满足条件
True表示该位置的元素 > 5,False表示不满足- 数据类型是
bool(布尔型)
第二步:arr[condition] 如何筛选数据?
# condition 是一个布尔数组
condition = arr > 5
print(condition)
# [[False False False False]
# [False True True True]
# [ True True True True]]
# 用布尔数组筛选元素
result = arr[condition]
print(result)
输出:
[ 6 7 8 9 10 11 12]
筛选原理:
NumPy 会遍历布尔数组,将所有对应位置为 True 的元素收集起来,返回一个一维数组。
可视化理解:
原始数组 arr: 条件 arr > 5: 筛选结果:
┌────┬────┬────┬────┐ ┌─────┬─────┬─────┬─────┐ ┌────┐
│ 1 │ 2 │ 3 │ 4 │ │False│False│False│False│ │ 6 │
├────┼────┼────┼────┤ ├─────┼─────┼─────┼─────┤ ├────┤
│ 5 │ 6 │ 7 │ 8 │ × │False│ True│ True│ True│ → │ 7 │
├────┼────┼────┼────┤ ├─────┼─────┼─────┼─────┤ ├────┤
│ 9 │ 10 │ 11 │ 12 │ × │ True│ True│ True│ True│ │ 8 │
└────┴────┴────┴────┘ └─────┴─────┴─────┴─────┘ ├────┤
│ 9 │
├────┤
│ 10 │
├────┤
│ 11 │
├────┤
│ 12 │
└────┘
详细对应关系:
| 位置 | 元素值 | 条件 (arr > 5) | 是否选中 |
|---|---|---|---|
| (0,0) | 1 | False | ❌ |
| (0,1) | 2 | False | ❌ |
| (0,2) | 3 | False | ❌ |
| (0,3) | 4 | False | ❌ |
| (1,0) | 5 | False | ❌ |
| (1,1) | 6 | True | ✅ 选中 |
| (1,2) | 7 | True | ✅ 选中 |
| (1,3) | 8 | True | ✅ 选中 |
| (2,0) | 9 | True | ✅ 选中 |
| (2,1) | 10 | True | ✅ 选中 |
| (2,2) | 11 | True | ✅ 选中 |
| (2,3) | 12 | True | ✅ 选中 |
注意:
- 布尔索引返回的是一维数组,丢失了原来的二维结构
- 如果需要保留结构,可以使用
np.where()
# np.where 保留原数组结构,不满足条件的用 0 填充
result = np.where(arr > 5, arr, 0)
print(result)
# [[ 0 0 0 0]
# [ 0 6 7 8]
# [ 9 10 11 12]]
2.2 练习题
练习2-1:补全代码,实现数组索引与切片
import numpy as np
arr = np.array([[10, 20, 30, 40],
[50, 60, 70, 80],
[90, 100, 110, 120]])
# TODO: 获取第1行第2列的元素(值为70),赋值给 elem
elem = __________
print(f"elem: {elem}")
# 预期输出: elem: 70
# TODO: 获取第2行所有元素 [90, 100, 110, 120],赋值给 row2
row2 = __________
print(f"row2: {row2}")
# 预期输出: row2: [ 90 100 110 120]
# TODO: 获取第1列所有元素 [20, 60, 100],赋值给 col1
col1 = __________
print(f"col1: {col1}")
# 预期输出: col1: [ 20 60 100]
# TODO: 获取左上角的 2x2 子矩阵 [[10, 20], [50, 60]],赋值给 sub
sub = __________
print(f"sub:\n{sub}")
# 预期输出:
# sub:
# [[10 20]
# [50 60]]
# TODO: 获取所有大于 50 的元素,赋值给 filtered
filtered = __________
print(f"filtered: {filtered}")
# 预期输出: filtered: [ 60 70 80 90 100 110 120]
三、数组运算
3.1 核心知识点
import numpy as np
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
# 元素级运算
print(a + b) # [5, 7, 9]
print(a * b) # [4, 10, 18]
print(a ** 2) # [1, 4, 9]
print(np.sqrt(a)) # [1., 1.414, 1.732]
常用运算函数:
| 函数 | 示例 | 说明 |
|---|---|---|
np.sum() |
np.sum(arr) |
求和 |
np.mean() |
np.mean(arr) |
平均值 |
np.max() |
np.max(arr) |
最大值 |
np.min() |
np.min(arr) |
最小值 |
np.std() |
np.std(arr) |
标准差 |
🔍 深入理解:np.sum() 和 np.mean() 的 axis 参数
axis 参数决定了沿着哪个方向进行计算:
import numpy as np
# 创建一个 3x4 的二维数组(3行4列)
arr = np.array([[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]])
print("原始数组:")
print(arr)
# [[ 1 2 3 4]
# [ 5 6 7 8]
# [ 9 10 11 12]]
# axis=0: 沿着行方向计算(对每列求和/求平均)
print("\nnp.sum(arr, axis=0) - 每列求和:")
print(np.sum(arr, axis=0)) # [15, 18, 21, 24]
print("\nnp.mean(arr, axis=0) - 每列求平均:")
print(np.mean(arr, axis=0)) # [5., 6., 7., 8.]
# axis=1: 沿着列方向计算(对每行求和/求平均)
print("\nnp.sum(arr, axis=1) - 每行求和:")
print(np.sum(arr, axis=1)) # [10, 26, 42]
print("\nnp.mean(arr, axis=1) - 每行求平均:")
print(np.mean(arr, axis=1)) # [2.5, 6.5, 10.5]
# 不指定 axis: 对所有元素求和/求平均
print("\nnp.sum(arr) - 所有元素求和:")
print(np.sum(arr)) # 78
print("\nnp.mean(arr) - 所有元素求平均:")
print(np.mean(arr)) # 6.5
可视化理解 axis 参数:
原始数组 (3行4列):
第0列 第1列 第2列 第3列
┌─────┐┌─────┐┌─────┐┌─────┐
第0行 │ 1 ││ 2 ││ 3 ││ 4 │
├─────┼┼─────┼┼─────┼┼─────┤
第1行 │ 5 ││ 6 ││ 7 ││ 8 │
├─────┼┼─────┼┼─────┼┼─────┤
第2行 │ 9 ││ 10 ││ 11 ││ 12 │
└─────┘└─────┘└─────┘└─────┘
axis=0 (沿着行方向 ↓,对每列计算):
↓ ↓ ↓ ↓
1+5+9 2+6+10 3+7+11 4+8+12
=15 =18 =21 =24
结果: [15, 18, 21, 24] (4个值,对应4列)
axis=1 (沿着列方向 →,对每行计算):
→ 1+2+3+4=10
→ 5+6+7+8=26
→ 9+10+11+12=42
结果: [10, 26, 42] (3个值,对应3行)
记忆技巧:
axis=0→ 想象成从上往下压扁,结果是每列的统计值axis=1→ 想象成从左往右压扁,结果是每行的统计值- 结果数组的形状:哪个 axis 被压缩了,那个维度就消失了
对比表:
| 操作 | 代码 | 结果 | 说明 |
|---|---|---|---|
| 每列求和 | np.sum(arr, axis=0) |
[15, 18, 21, 24] |
沿着行方向,每列一个结果 |
| 每行求和 | np.sum(arr, axis=1) |
[10, 26, 42] |
沿着列方向,每行一个结果 |
| 全体求和 | np.sum(arr) |
78 |
所有元素求和 |
| 每列平均 | np.mean(arr, axis=0) |
[5., 6., 7., 8.] |
沿着行方向,每列一个结果 |
| 每行平均 | np.mean(arr, axis=1) |
[2.5, 6.5, 10.5] |
沿着列方向,每行一个结果 |
| 全体平均 | np.mean(arr) |
6.5 |
所有元素求平均 |
3.2 练习题
练习3-1:补全代码,实现数组运算
import numpy as np
a = np.array([10, 20, 30, 40])
b = np.array([2, 4, 6, 8])
# TODO: 计算 a + b,赋值给 sum_arr
sum_arr = __________
print(f"sum_arr: {sum_arr}")
# 预期输出: sum_arr: [12 24 36 48]
# TODO: 计算 a * b(元素乘法),赋值给 mul_arr
mul_arr = __________
print(f"mul_arr: {mul_arr}")
# 预期输出: mul_arr: [ 20 80 180 320]
# TODO: 计算 a 的平均值,赋值给 mean_val
mean_val = __________
print(f"mean_val: {mean_val}")
# 预期输出: mean_val: 25.0
# TODO: 计算 a 的最大值,赋值给 max_val
max_val = __________
print(f"max_val: {max_val}")
# 预期输出: max_val: 40
# TODO: 计算 a 的标准差,赋值给 std_val
std_val = __________
print(f"std_val: {std_val}")
# 预期输出: std_val: 11.180339887498949
# 创建一个 3x4 的二维数组用于 axis 练习
matrix = np.array([[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]])
print(f"matrix:\n{matrix}")
# TODO: 计算 matrix 每行的和,赋值给 row_sums
# 提示: 使用 axis 参数
row_sums = __________
print(f"row_sums: {row_sums}")
# 预期输出: row_sums: [10 26 42]
# TODO: 计算 matrix 每列的平均值,赋值给 col_means
# 提示: 使用 axis 参数
col_means = __________
print(f"col_means: {col_means}")
# 预期输出: col_means: [5. 6. 7. 8.]
# TODO: 计算 matrix 所有元素的总和,赋值给 total_sum
total_sum = __________
print(f"total_sum: {total_sum}")
# 预期输出: total_sum: 78
四、数组形状操作
4.1 核心知识点
import numpy as np
arr = np.arange(12) # [0, 1, 2, ..., 11]
# 改变形状
arr_2d = arr.reshape(3, 4) # 3行4列
arr_flat = arr_2d.flatten() # 展平为一维
# 拼接与分割
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])
np.vstack((a, b)) # 垂直拼接
np.hstack((a, b)) # 水平拼接
形状操作函数:
| 函数 | 示例 | 说明 |
|---|---|---|
reshape() |
arr.reshape(3, 4) |
改变形状 |
flatten() |
arr.flatten() |
展平为一维 |
vstack() |
np.vstack((a, b)) |
垂直拼接 |
hstack() |
np.hstack((a, b)) |
水平拼接 |
4.2 练习题
练习4-1:补全代码,实现数组形状操作
import numpy as np
arr = np.arange(12)
print(f"原始数组: {arr}")
# 预期输出: 原始数组: [ 0 1 2 3 4 5 6 7 8 9 10 11]
# TODO: 将 arr 重塑为 3x4 的矩阵,赋值给 matrix
matrix = __________
print(f"matrix:\n{matrix}")
# 预期输出:
# matrix:
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
# TODO: 获取 matrix 的转置,赋值给 matrix_T
matrix_T = __________
print(f"matrix_T:\n{matrix_T}")
# 预期输出:
# matrix_T:
# [[ 0 4 8]
# [ 1 5 9]
# [ 2 6 10]
# [ 3 7 11]]
# TODO: 将 matrix 展平为一维数组,赋值给 flat_arr
flat_arr = __________
print(f"flat_arr: {flat_arr}")
# 预期输出: flat_arr: [ 0 1 2 3 4 5 6 7 8 9 10 11]
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])
# TODO: 垂直拼接 a 和 b,赋值给 v_combined
v_combined = __________
print(f"v_combined:\n{v_combined}")
# 预期输出:
# v_combined:
# [[1 2]
# [3 4]
# [5 6]
# [7 8]]
# TODO: 水平拼接 a 和 b,赋值给 h_combined
h_combined = __________
print(f"h_combined:\n{h_combined}")
# 预期输出:
# h_combined:
# [[1 2 5 6]
# [3 4 7 8]]
五、广播机制
5.1 核心知识点
广播 允许不同形状的数组进行运算。
import numpy as np
# 标量广播
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr + 10) # [[11, 12, 13], [14, 15, 16]]
# 一维数组广播到二维
arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
row = np.array([10, 20, 30])
print(arr + row) # 每行都加上 [10, 20, 30]
5.2 练习题
练习5-1:补全代码,理解广播机制
import numpy as np
matrix = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
# TODO: 将 matrix 每个元素都加上 100,赋值给 added
added = __________
print(f"added:\n{added}")
# 预期输出:
# added:
# [[101 102 103]
# [104 105 106]
# [107 108 109]]
# TODO: 将 matrix 每个元素都乘以 2,赋值给 multiplied
multiplied = __________
print(f"multiplied:\n{multiplied}")
# 预期输出:
# multiplied:
# [[ 2 4 6]
# [ 8 10 12]
# [14 16 18]]
row_vector = np.array([10, 20, 30])
# TODO: 将 matrix 的每一行都加上 row_vector,赋值给 row_added
row_added = __________
print(f"row_added:\n{row_added}")
# 预期输出:
# row_added:
# [[11 22 33]
# [14 25 36]
# [17 28 39]]
六、综合练习
练习6-1:学生成绩统计分析
import numpy as np
# 3个学生,4门课程的成绩
scores = np.array([
[85, 90, 78, 92], # 学生1
[76, 88, 95, 80], # 学生2
[90, 85, 88, 94] # 学生3
])
# TODO: 计算每个学生的平均分,赋值给 student_means
# 提示: axis=1 表示按行计算
student_means = __________
print(f"每个学生的平均分: {student_means}")
# 预期输出: 每个学生的平均分: [86.25 84.75 89.25]
# TODO: 计算每门课程的平均分,赋值给 course_means
# 提示: axis=0 表示按列计算
course_means = __________
print(f"每门课程的平均分: {course_means}")
# 预期输出: 每门课程的平均分: [83.66666667 87.66666667 87. 88. ]
# TODO: 找出平均分最高的学生的索引,赋值给 best_student_idx
best_student_idx = __________
print(f"最高分学生索引: {best_student_idx}")
# 预期输出: 最高分学生索引: 2
# TODO: 将所有成绩转换为百分制(满分100,已经是百分制),
# 然后找出所有大于90分的成绩,赋值给 high_scores
high_scores = __________
print(f"高于90分的成绩: {high_scores}")
# 预期输出: 高于90分的成绩: [92 95 94]
附录:答案
练习1-1 答案
arr1 = np.array([10, 20, 30, 40, 50])
zeros_arr = np.zeros((3, 3))
range_arr = np.arange(0, 20, 4)
lin_arr = np.linspace(0, 1, 5)
rand_arr = np.random.rand(2, 3)
# 按行列取值答案
elem = matrix[1, 2]
row2 = matrix[2, :]
col0 = matrix[:, 0]
sub = matrix[0:2, 0:2]
练习2-1 答案
elem = arr[1, 2]
row2 = arr[2, :]
col1 = arr[:, 1]
sub = arr[0:2, 0:2]
filtered = arr[arr > 50]
练习3-1 答案
sum_arr = a + b
mul_arr = a * b
mean_val = np.mean(a)
max_val = np.max(a)
std_val = np.std(a)
# axis 练习答案
row_sums = np.sum(matrix, axis=1)
col_means = np.mean(matrix, axis=0)
total_sum = np.sum(matrix)
练习4-1 答案
matrix = arr.reshape(3, 4)
flat_arr = matrix.flatten()
v_combined = np.vstack((a, b))
h_combined = np.hstack((a, b))
练习5-1 答案
added = matrix + 100
multiplied = matrix * 2
row_added = matrix + row_vector
练习6-1 答案
student_means = np.mean(scores, axis=1)
course_means = np.mean(scores, axis=0)
best_student_idx = np.argmax(student_means)
high_scores = scores[scores > 90]
快速参考表
| 操作 | 代码 | 说明 |
|---|---|---|
| 创建数组 | np.array([1, 2, 3]) |
从列表创建 |
| 全0数组 | np.zeros((3, 3)) |
3x3全0 |
| 全1数组 | np.ones((2, 4)) |
2x4全1 |
| 等差数列 | np.arange(0, 10, 2) |
0到10,步长2 |
| 等分数列 | np.linspace(0, 1, 5) |
0到1,5个数 |
| 随机数 | np.random.rand(3, 3) |
3x3随机数 |
| 索引 | arr[1, 2] |
第1行第2列 |
| 切片 | arr[0:2, :] |
前2行 |
| 布尔索引 | arr[arr > 5] |
大于5的元素 |
| 求和 | np.sum(arr) |
所有元素和 |
| 均值 | np.mean(arr) |
平均值 |
| 最大值 | np.max(arr) |
最大值 |
| 最小值 | np.min(arr) |
最小值 |
| 标准差 | np.std(arr) |
标准差 |
| 重塑 | arr.reshape(3, 4) |
改变形状 |
| 展平 | arr.flatten() |
变为一维 |
| 垂直拼接 | np.vstack((a, b)) |
上下拼接 |
| 水平拼接 | np.hstack((a, b)) |
左右拼接 |
浙公网安备 33010602011771号