动手示例展示 NumPy 数组的创建和操作。这些数组对于在 Python 中高效进行线性代数运算非常重要。我们将遵循将 NumPy 导入为 np 的常用约定。import numpy as np如果您尚未安装 NumPy,请回顾第 1 章中的“设置 Python 环境”部分。创建数组首先,我们再次看看如何创建数组。最直接的方法通常是使用 np.array() 从现有的 Python 列表或元组创建。从 Python 列表创建:# 创建一个一维数组(向量) list_a = [1, 5, 2, 7] vector_a = np.array(list_a) print("从列表创建的向量:") print(vector_a) print("数据类型:", vector_a.dtype) # 检查推断的数据类型 # 创建一个二维数组(矩阵) list_b = [[1, 2, 3], [4, 5, 6]] matrix_b = np.array(list_b) print("\n从列表的列表创建的矩阵:") print(matrix_b) print("数据类型:", matrix_b.dtype)请注意 NumPy 如何自动推断数据类型(例如 int64 或 float64)。您也可以使用 dtype 参数明确指定数据类型:# 创建一个浮点数组 matrix_c = np.array([[1, 2], [3, 4]], dtype=np.float64) print("\n指定浮点类型的矩阵:") print(matrix_c) print("数据类型:", matrix_c.dtype)使用 NumPy 函数创建:NumPy 提供了一些函数来创建具有特定模式的数组,这通常比先创建 Python 列表更高效。np.zeros(): 创建一个全为零的数组。np.ones(): 创建一个全为一的数组。np.arange(): 创建一个包含一系列数字的数组(类似于 Python 的 range)。np.linspace(): 在指定区间内创建一个等间隔数字的数组。# 创建一个 3x4 的零矩阵 zeros_matrix = np.zeros((3, 4)) # 将形状作为元组传递 print("\n3x4 零矩阵:") print(zeros_matrix) # 创建一个一维全一数组 ones_vector = np.ones(5) print("\n全一向量:") print(ones_vector) # 创建一个从 0 开始到(但不包括)10 的数组 range_array = np.arange(10) print("\n使用 arange(10) 创建的数组:") print(range_array) # 创建一个从 2 开始到 10,步长为 2 的数组 range_step_array = np.arange(2, 11, 2) # 起始值,结束值(不包含),步长 print("\n使用 arange(2, 11, 2) 创建的数组:") print(range_step_array) # 创建一个在 0 到 1 之间包含 5 个等间隔点的数组 linspace_array = np.linspace(0, 1, 5) # 起始值,结束值(包含),点的数量 print("\n使用 linspace(0, 1, 5) 创建的数组:") print(linspace_array)访问和修改元素:索引和切片一旦您有了数组,就需要访问它的元素。NumPy 使用零基索引,这与 Python 列表类似。一维数组:my_vector = np.arange(5, 11) # 创建 [5, 6, 7, 8, 9, 10] print("\n原始向量:", my_vector) # 访问第一个元素(索引 0) first_element = my_vector[0] print("第一个元素:", first_element) # 访问最后一个元素(索引 -1) last_element = my_vector[-1] print("最后一个元素:", last_element) # 获取切片:从索引 1 开始到(但不包括)索引 4 的元素 slice_1_to_3 = my_vector[1:4] print("切片 [1:4]:", slice_1_to_3) # 获取切片:从开头到索引 3 的元素 slice_start_to_2 = my_vector[:3] print("切片 [:3]:", slice_start_to_2) # 获取切片:从索引 3 到末尾的元素 slice_3_to_end = my_vector[3:] print("切片 [3:]:", slice_3_to_end) # 修改一个元素 my_vector[2] = 99 print("修改后的向量:", my_vector) # 修改一个切片 my_vector[0:2] = [100, 101] # 赋值一个列表或另一个 NumPy 数组 print("切片修改后的向量:", my_vector)二维数组(矩阵):对于二维数组,您可以使用逗号分隔的索引或切片:[行索引, 列索引] 或 [行切片, 列切片]。my_matrix = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) print("\n原始矩阵:") print(my_matrix) # 访问第 1 行、第 2 列的元素(值为 6) element_1_2 = my_matrix[1, 2] print("元素位于 [1, 2]:", element_1_2) # 访问整个第二行(索引 1) row_1 = my_matrix[1, :] # 使用 ':' 选择所有列 print("第二行:", row_1) # 选择整行的另一种语法 row_1_alt = my_matrix[1] print("第二行(另一种方式):", row_1_alt) # 访问整个第三列(索引 2) col_2 = my_matrix[:, 2] # 使用 ':' 选择所有行 print("第三列:", col_2) # 获取子矩阵:第 0 和 1 行,第 1 和 2 列 sub_matrix = my_matrix[0:2, 1:3] print("\n子矩阵 [0:2, 1:3]:") print(sub_matrix) # 修改一个元素 my_matrix[0, 0] = -1 print("\n修改元素 [0, 0] 后的矩阵:") print(my_matrix) # 修改一列 my_matrix[:, 0] = [10, 20, 30] # 赋值一个正确大小的列表或数组 print("\n修改第一列后的矩阵:") print(my_matrix)基本算术运算NumPy 允许您直接对数组进行按元素的算术运算,前提是它们的形状兼容(或可广播,我们稍后会提到这一点)。arr1 = np.array([1, 2, 3]) arr2 = np.array([4, 5, 6]) scalar = 2 print("\n数组 1:", arr1) print("数组 2:", arr2) print("标量:", scalar) # 按元素加法 addition = arr1 + arr2 print("arr1 + arr2:", addition) # 按元素减法 subtraction = arr1 - arr2 print("arr1 - arr2:", subtraction) # 按元素乘法 multiplication = arr1 * arr2 print("arr1 * arr2:", multiplication) # 按元素除法 division = arr1 / arr2 print("arr1 / arr2:", division) # 标量乘法 scalar_mult = arr1 * scalar print("arr1 * 标量:", scalar_mult) # 标量加法(将标量添加到每个元素) scalar_add = arr1 + scalar print("arr1 + 标量:", scalar_add) # 矩阵操作类似 matrix1 = np.array([[1, 2], [3, 4]]) matrix2 = np.array([[5, 6], [7, 8]]) print("\n矩阵 1:") print(matrix1) print("矩阵 2:") print(matrix2) matrix_sum = matrix1 + matrix2 print("矩阵和:") print(matrix_sum) matrix_prod = matrix1 * matrix2 # 注意:这是按元素乘法 print("矩阵按元素乘积:") print(matrix_prod)重要提示: * 运算符对 NumPy 数组执行按元素乘法。这与标准矩阵乘法(点积)不同,我们将在第 5 章中详细介绍后者。理解数组属性和形状更改了解数组的属性很重要。NumPy 数组有几个有用的属性:ndim: 维度数量。shape: 一个元组,表示数组在每个维度(行、列等)上的大小。size: 数组中元素的总数量。dtype: 元素的数值类型。matrix = np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) print("\n示例矩阵:") print(matrix) print("维度数量 (ndim):", matrix.ndim) print("形状 (shape):", matrix.shape) # (行数, 列数) print("总大小 (size):", matrix.size) print("数据类型 (dtype):", matrix.dtype)您可以使用 reshape() 方法在不改变数组数据的情况下改变其形状。新的形状必须具有相同的元素总数(size)。vector = np.arange(12) # 数组从 0 到 11 print("\n原始向量(大小 12):", vector) # 重塑为 3x4 矩阵 (3*4 = 12 个元素) matrix_3x4 = vector.reshape(3, 4) print("\n重塑为 3x4 矩阵:") print(matrix_3x4) print("新形状:", matrix_3x4.shape) # 重塑为 4x3 矩阵 (4*3 = 12 个元素) matrix_4x3 = vector.reshape(4, 3) print("\n重塑为 4x3 矩阵:") print(matrix_4x3) print("新形状:", matrix_4x3.shape) # 尝试重塑为不兼容的形状(例如,3x5 = 15 个元素) try: vector.reshape(3, 5) except ValueError as e: print("\n重塑错误(预期):", e) # 在 reshape 中使用 -1:NumPy 会自动计算维度 # 重塑为 2 行矩阵(NumPy 会计算列数) matrix_2x_auto = vector.reshape(2, -1) # -1 表示“自动推断” print("\n重塑为 2 行(自动列):") print(matrix_2x_auto) print("新形状:", matrix_2x_auto.shape) # 将是 (2, 6) # 重塑为 3 列矩阵(NumPy 会计算行数) matrix_auto_x3 = vector.reshape(-1, 3) print("\n重塑为 3 列(自动行):") print(matrix_auto_x3) print("新形状:", matrix_auto_x3.shape) # 将是 (4, 3)形状更改在机器学习中经常使用,用于为不同的算法或神经网络层准备数据,因为它们通常需要特定维度的输入。这些示例涵盖了 NumPy 数组创建、访问、修改和检查的基本机制。随着您课程的推进,您会看到这些操作在线性代数的向量和矩阵中使用。花一些时间练习这些函数和操作,以便熟悉它们。它们是未来更复杂计算的组成部分。