
在 NumPy 中数组ndarray中的数据通常需要通过索引indexing和切片slicing进行访问或修改。索引机制不仅决定了如何获取数组中的元素也直接影响数据是否共享内存以及运算效率。NumPy 的索引机制在继承 Python 序列如列表和字符串索引规则的基础上进行了扩展使其能够高效地处理多维数组、条件筛选以及复杂的数据选择。在 NumPy 中数组索引通常可以分为两大类1基本索引Basic Indexing• 整数索引• 切片访问• 多维数组的整数索引• 维度扩展• 省略符2高级索引Advanced Indexing• 整数数组索引• 布尔数组索引在实际使用中两者也可以同时出现在同一表达式中这种情况通常称为混合索引Mixed Indexing。一、基本索引基本索引是 NumPy 中最基础的数组访问方式其行为与 Python 序列类型如列表、字符串的索引和切片规则基本一致。1、整数索引整数索引用于访问数组中的单个元素。示例import numpy as np a np.array([10, 20, 30, 40]) print(a[0])# 10说明a[0] 表示访问数组中的第一个元素。NumPy 也支持负索引用于从数组末尾开始访问。示例print(a[-1])# 40说明-1 表示最后一个元素-2 表示倒数第二个元素如此类推。提示当整数索引用于定位单个元素时返回结果通常是 NumPy 标量scalar而不是数组对象。2、切片访问切片用于访问数组中的一段连续元素。语法结构array[start:stop:step]含义• start起始位置包含• stop结束位置不包含• step步长示例a np.array([10, 20, 30, 40, 50]) print(a[1:4])# [20 30 40]说明返回索引 1 到 3 的元素。切片参数可以省略。示例a[:3]# [10 20 30] a[2:]# [30 40 50] a[::2]# [10 30 50]也可以通过负步长实现数组反向。示例a[::-1]# [50 40 30 20 10]说明[::-1] 是数组反转的常见写法。3、多维数组索引对于多维数组需要使用逗号分隔各个维度的索引。1访问单个元素a np.array([[1, 2, 3], [4, 5, 6]]) print(a[0, 1])# 2说明a[0,1] 表示第 0 行第 1 列的元素。2访问整行a[1]# [4 5 6]说明a[1] 表示取第 1 行数据。对普通 ndarray 而言这种基本索引通常返回原数组上的一个一维视图。或者a[1,:]# [4 5 6]3访问整列a[:, 1]# [2 5]说明: 表示该维度的全部元素。4子数组切片示例a np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) print(a[0:2, 1:3])输出[[2 3] [5 6]]说明0:2 表示选择前两行1:3 表示选择第 2、3 列。4、基本索引的维度规则在 NumPy 的基本索引中不同类型的索引对象会对数组维度产生不同影响。1整数索引会定位该维度上的一个元素并消除该维度。2切片访问会选择该维度上的一段范围并保留该维度。示例a np.arange(24).reshape(2,3,4) print(a[0].shape) # (3,4)print(a[0:1].shape) # (1,3,4)说明a[0] 使用整数索引因此第 0 维被消除。a[0:1] 使用切片访问因此第 0 维被保留。在基本索引中整数索引会消除该维度而切片访问会保留该维度。3维度扩展np.newaxis 是一个特殊对象等价于 None其本质是在索引表达式中插入长度为 1 的新维度。它通常只在索引语法中使用而不是作为数组函数调用。示例a np.array([1, 2, 3]) print(a[:, np.newaxis])输出[[1] [2] [3]]说明数组形状从 (3,) 变为 (3,1)。4省略符省略符ellipsis ... 用于表示若干个连续维度等价于使用多个 : 展开。示例a np.arange(24).reshape(2, 3, 4) print(a[..., 0])相当于a[:, :, 0]要注意的是一个索引表达式中通常只能出现一个省略符。5、基本切片通常返回视图基本索引通常返回原数组的视图view即新数组与原数组共享同一块内存而不是数据副本这意味着修改结果可能会影响原数组。示例a np.array([1, 2, 3, 4]) b a[1:3] b[0] 99print(a)# [ 1 99 3 4]提示修改切片内容会影响原数组。若希望切片结果与原数组彻底分离应对切片结果调用 .copy()b a[1:3].copy()二、高级索引当索引表达式中包含以下对象时NumPy 会启用高级索引也称“花式索引” fancy indexing• 整数数组• 布尔数组与基本索引不同高级索引具有两个重要特点1可以选择不连续元素2基本索引通常返回视图view而高级索引的取值结果始终是副本copy1、整数数组索引NumPy 支持使用整数数组索引来一次访问多个指定位置的元素。1一维数组的整数数组索引示例a np.array([10, 20, 30, 40]) index [0, 2, 3]print(a[index])# [10 30 40]或者print(a[[0, 2, 3]])说明整数数组 [0,2,3] 指定需要访问的元素位置。2多维数组的整数数组索引每个维度使用一个整数数组索引维度之间用逗号分隔。示例a np.array([[1, 2], [3, 4], [5, 6]]) rows [0, 2]cols [1, 0]print(a[rows, cols])# [2 5]或者print(a[[0, 2],[1, 0]])说明输出的对应元素是 a[0,1] 和 a[2,0]。2、布尔数组索引布尔索引用一个布尔数组作为筛选条件True 位置对应的元素将被选择。布尔索引要求布尔数组与被索引部分的形状相匹配。例如对一维数组进行布尔筛选时布尔数组长度必须与原数组长度一致对多维数组某一轴进行筛选时布尔数组长度必须与该轴长度一致。若形状不匹配NumPy 会抛出错误。示例a np.array([1, 2, 3, 4, 5]) mask a 3 print(a[mask])# [4 5]或者直接使用条件表达式print(a[a 3])说明a 3 会构建一个布尔数组[False, False, False, True, True]a[a 3] 则只返回条件为 True 的元素。也可直接使用自定义的布尔数组print(a[[False, False, False, True, True]])NumPy 使用 按位与和 |按位或进行逻辑运算以实现多条件筛选。示例a np.array([1, 2, 3, 4, 5, 6]).reshape(2, 3) print(a[(a 2) (a 6)])# [3 4 5]其实质是两个布尔数组进行逻辑运算后得到一个新的布尔数组作为条件筛选的依据。当使用与原数组同形状的布尔数组进行筛选时结果通常会以一维数组的形式返回所有满足条件的元素。提示• 对数组条件进行组合时应使用 和 |而不能使用 Python 的 and 和 or• 多个条件表达式必须使用括号包裹三、混合索引当基本索引与高级索引同时出现在同一个索引表达式中时就形成了混合索引。示例a np.arange(12).reshape(3,4) print(a[:, [1, 3]])输出[[ 1 3] [ 5 7] [ 9 11]]解释此处的 : 为基本索引切片表示选择第 0 维度的全部元素所有行。而 [1,3] 为整数数组索引表示在第 1 维度列维度选择第 1 列和第 3 列。因此这是一个混合索引。在混合索引中只要索引表达式中包含高级索引整数数组或布尔数组NumPy 就会启用高级索引机制并返回新的数组副本。因此a[:, [1,3]] 的返回值是 copy而不是 view。需要注意的是在更复杂的混合索引中高级索引参与结果形状的方式可能并不完全符合初学者的直觉因此在多维数组场景下最好通过 shape 明确检查结果结构。四、索引与切片相关函数NumPy 提供了一组用于数组索引与元素选择的函数可在多维数组中高效定位、筛选和提取数据。• 获取元素的索引argmax()、argmin()、argwhere()、nonzero()• 条件筛选与元素选择where()• 根据索引或条件提取数组元素take()、choose()、take_along_axis()、compress()、extract()• 在线性索引与多维坐标之间进行转换unravel_index()、ravel_multi_index()• 访问与计算数组的对角线元素diagonal() 、trace()这些函数共同构成了 NumPy 数组数据访问与选择的重要工具。详情请参阅NumPy 函数手册数组索引与切片 小结NumPy 的索引机制使数组数据能够以灵活而高效的方式被访问和选择。通过整数索引、切片、条件筛选以及多维索引表达式可以精确地定位数组中的元素或子数组。需要注意的是不同索引方式在内存行为上存在差异有些操作返回原数组的视图有些则生成新的数据副本。理解这些规则是正确处理数组数据与避免隐式数据修改的重要基础。“点赞有美意赞赏是鼓励”