NumPy-Exercises

Author Avatar
小包
发表:2025-09-11 14:34:02
修改:2025-09-11 15:13:03

第一部分:创建数组 (Array Creation)

1. 将 NumPy 库导入为 np

这是使用 NumPy 的标准约定。

import numpy as np

2. 创建一个包含10个0的数组

NumPy 提供了专门的函数来创建全0或全1的数组。

代码:

np.zeros(10)

解释: np.zeros() 函数会创建一个指定形状、并用0填充的数组。参数 10 定义了这是一个包含10个元素的一维数组。请注意,默认的数据类型是浮点数 (0.)。


3. 创建一个包含10个1的数组

这与创建全0数组非常类似。

代码:

np.ones(10)

解释: np.ones() 函数会创建一个指定形状、并用1填充的数组。与 np.zeros() 类似,默认的数据类型也是浮点数 (1.)。


4. 创建一个包含10个5的数组

NumPy 没有直接的 np.fives() 函数,但这可以通过简单的运算实现。

代码方法一:

np.ones(10) * 5

代码方法二(更直接):

np.full(10, 5)

解释:

  • 方法一: 我们先创建一个包含10个1的数组 [1., 1., ..., 1.],然后利用 NumPy 的向量化操作,将数组中的每个元素都乘以5。
  • 方法二: np.full(shape, fill_value) 函数是更直接的方式,它可以创建一个指定 shape (形状) 并用 fill_value (填充值) 填充的数组。对于这个任务,此方法更佳。

5. 创建一个从10到50的整数数组

要创建连续的数字序列,NumPy 的 arange 函数是首选。

代码:

np.arange(10, 51)

解释: np.arange(start, stop) 的功能类似于 Python 内置的 range() 函数,但它返回的是一个 NumPy 数组。start 参数是包含的,而 stop 参数是不包含的(也就是常说的“包头不包尾”)。因此,为了让数组包含 50stop 参数必须设置为 51


6. 创建一个从10到50的所有偶数整数数组

np.arange 还可以接受第三个参数 step(步长)。

代码:

np.arange(10, 51, 2)

解释: np.arange(start, stop, step) 会生成一个从 start 开始,每次递增 step,并在到达 stop 之前结束的序列。这里我们指定步长为 2,从而只获取偶数。


7. 创建一个3x3的矩阵,其值范围从0到8

这通常需要两步操作:先创建一维数组,然后将其重塑为二维矩阵。

代码:

np.arange(9).reshape(3, 3)

解释:

  1. np.arange(9) 创建一个包含0到8整数的一维数组:[0, 1, 2, 3, 4, 5, 6, 7, 8]
  2. .reshape(rows, cols) 方法被调用,将这个一维数组的形状改变为一个3行3列的矩阵。数组的元素总数必须与新形状的容量相匹配(9个元素 = 3 * 3)。

8. 创建一个3x3的单位矩阵

单位矩阵是一个特殊的方阵,其主对角线上的值为1,其余位置为0。

代码:

np.eye(3)

解释: np.eye(N) 函数用于创建一个 N x N 的单位矩阵。


9. 使用 NumPy 生成一个0到1之间的随机数

NumPy 拥有一个强大的 random 子模块用于生成随机数据。

代码:

np.random.rand(1)

解释: np.random.rand() 会创建一个指定形状的数组,并用来自 [0, 1) 区间上均匀分布的随机样本填充它。参数 1 表示我们想要一个值(它会被返回在一个数组里)。


10. 使用 NumPy 生成一个由25个标准正态分布样本组成的数组

代码:

np.random.randn(25)

解释: np.random.randn() 会创建一个指定形状的数组,并用来自标准正态分布(均值为0,方差为1)的样本填充。这与 rand()(均匀分布)是不同的。


11. 创建指定的10x10矩阵

这需要结合 arangereshape 和向量化运算。

代码:

np.arange(1, 101).reshape(10, 10) / 100

解释:

  1. np.arange(1, 101) 创建从1到100的整数。
  2. .reshape(10, 10) 将其变为10x10的矩阵。
  3. / 100 是一个向量化操作,它会将矩阵中的每一个元素都除以100,从而得到最终结果。

12. 创建一个在0和1之间线性等分的20个点的数组

“线性等分”是这里的关键词,它指向一个特定的函数。

代码:

np.linspace(0, 1, 20)

解释: np.linspace(start, stop, num) 会创建一个包含 num 个点的数组,这些点在 [start, stop] 区间内均匀分布。与 arange 不同,它的 stop 值默认是包含在内的。这个函数非常适合此类任务。


第二部分:NumPy 索引和选择 (Indexing and Selection)

首先,请确保你已经运行了定义 mat 变量的那个单元格,因为后面的所有问题都依赖于它。

# 运行此单元格 - 这是我们的起始矩阵
mat = np.arange(1,26).reshape(5,5)

13. 重现输出 [[12, 13, 14, 15], [17, 18, 19, 20], [22, 23, 24, 25]]

代码:

mat[2:, 1:]

解释: NumPy 的二维数组索引格式为 mat[rows, columns]。切片 (start:stop) 可用于两个维度。

  • 2: 用于行,表示“从索引2开始选择到末尾的所有行”。(这会得到 [11, ...][16, ...][21, ...] 这三行)。
  • 1: 用于列,表示“从索引1开始选择到末尾的所有列”。 这两个切片的交集就是我们想要的子矩阵。

14. 重现输出 20

代码:

mat[3, 4]

解释: 要选择单个元素,只需提供其精确的坐标 mat[row_index, column_index]。元素 20 位于第3行(索引从0开始)和第4列。


15. 重现输出 [[2], [7], [12]]

代码:

mat[:3, 1:2]

解释: 这展示了索引和切片之间的一个关键区别。

  • 如果使用 mat[:3, 1],虽然会选中正确的数字,但它会返回一个一维数组 [2, 7, 12]
  • 为了保持二维的列向量形状,我们必须对列进行切片1:2 选择了索引为1的列,并保持结果为二维数组的格式。

16. 重现输出 [21, 22, 23, 24, 25]

代码:

mat[4]

或者:

mat[-1]

解释: 要选择一整行,你只需提供该行的索引。同时也支持负数索引(-1 代表最后一个元素),这通常很方便。


17. 重现输出 [[16, 17, 18, 19, 20], [21, 22, 23, 24, 25]]

代码:

mat[3:]

解释: 这是一个简单的行切片操作。3: 表示选择从索引3开始到矩阵末尾的所有行。


第三部分:NumPy 运算 (Operations)

18. 获取 mat 矩阵中所有值的总和

代码:

mat.sum()

或者:

np.sum(mat)

解释: 可以直接在 NumPy 数组上调用 .sum() 方法来计算其所有元素的和。


19. 获取 mat 矩阵中所有值的标准差

代码:

mat.std()

解释:.sum() 类似,.std() 方法用于计算数组中所有元素的标准差。


20. 获取 mat 矩阵中所有列的总和

代码:

mat.sum(axis=0)

解释:sum 这样的运算可以沿着指定的轴 (axis) 进行。

  • axis=0 表示沿着“第0个轴”(即的方向)进行计算,实际上是把每一的元素加起来。
  • axis=1 表示沿着“第1个轴”(即的方向)进行计算,实际上是把每一的元素加起来。 因此,要得到每一列的和,我们使用 axis=0

附加题 (Bonus Question)

问题: 有没有办法确保我们每次都能得到相同的随机数?

答案: 有,通过设置随机种子 (random seed)

代码示例:

# 设置一个种子
np.random.seed(101)

# 生成一些随机数
print(np.random.rand(4))

# 再生成一些
print(np.random.rand(4))

# 重新将种子设为相同的值
np.random.seed(101)

# 你会发现,第一组随机数被重新生成了一遍
print(np.random.rand(4))

解释: 计算机中的随机数生成器实际上是伪随机的;它们是根据一个初始值(即种子)通过特定算法计算出的数字序列。这个序列看起来是随机的,但只要种子相同,生成的序列就完全相同。通过在生成随机数之前调用 np.random.seed() 设置一个固定的种子,你可以保证每次运行代码时都会得到完全一样的“随机”数序列。这对于需要复现实验结果的科学研究,以及调试含有随机性的代码至关重要。

评论