视频链接

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)) 左右拼接
posted on 2026-02-10 11:37  Yancey_chan  阅读(34)  评论(0)    收藏  举报