NumPy整数数组索引工作原理解析及相关疑问解答
嘿,我来帮你把这个容易搞懵的知识点掰扯明白!NumPy的整数数组索引初看有点绕,但拆解开核心逻辑其实挺直观的——它本质上是让你非连续、甚至重复地选取数组中特定位置的元素,和普通的单索引、切片完全不是一回事儿。
先从一维数组入手,最简单的情况
先拿一维数组举例子,一目了然:
import numpy as np arr = np.array([10, 20, 30, 40, 50])
如果我想选第0、2、4位的元素,不用一个个写arr[0], arr[2], arr[4],直接用一个整数列表/数组当索引:
indices = [0, 2, 4] result = arr[indices] # 输出:array([10, 30, 50])
这里的逻辑超级直白:索引数组里的每个整数,对应原数组中该位置的元素,最终把这些元素按索引数组的顺序拼成新数组。甚至你可以重复选同一个元素,比如indices = [0,0,1],结果就是array([10,10,20])。
二维数组才是重点,搞懂对应关系就通了
二维数组的整数索引容易懵,核心要记住:行和列的索引是一一对应的,不是“选某几行加某几列”(那是切片的活儿)。
先定义一个二维数组:
arr_2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
情况1:用两个一维数组指定行和列
比如我给出行索引rows = [0, 1, 2],列索引cols = [1, 2, 0],执行arr_2d[rows, cols],得到的结果是array([2, 6, 7])。
这里的对应逻辑是:
- 第0个元素:行索引0 + 列索引1 → 原数组的
arr_2d[0,1] = 2 - 第1个元素:行索引1 + 列索引2 → 原数组的
arr_2d[1,2] = 6 - 第2个元素:行索引2 + 列索引0 → 原数组的
arr_2d[2,0] = 7
简单说就是两个索引数组的相同位置元素配对,取出对应位置的单个元素,再按顺序组合。
情况2:混合整数索引和切片
如果只想选特定的几行,然后保留所有列(或某几列切片),可以这么写:
# 选第0行和第2行的所有元素 result = arr_2d[[0, 2], :] # 输出: # array([[1, 2, 3], # [7, 8, 9]])
这里的逻辑是先通过整数数组选出指定行,再对这些行应用列的切片规则(:表示所有列),这个就和你平时用切片的逻辑衔接上了。
情况3:利用广播实现批量选取
如果索引数组的形状不一样,NumPy会自动广播成相同形状,然后再配对选取。比如:
rows = np.array([[0, 0], [1, 1]]) # 形状(2,2) cols = np.array([[0, 1], [2, 0]]) # 形状(2,2) result = arr_2d[rows, cols] # 输出: # array([[1, 2], # [6, 4]])
每个位置的元素都是行和列索引对应位置的组合,比如rows[0,0]=0 + cols[0,0]=0 → 1,rows[1,1]=1 + cols[1,1]=0 → 4,以此类推。
关键误区要避开
很多人一开始会把整数数组索引和切片搞混:
- 如果你想选“第0、1行,第0、1列”的子数组,要用切片:
arr_2d[0:2, 0:2],得到的是2x2的子数组 - 而
arr_2d[[0,1], [0,1]]得到的是array([1,5]),是两个单个元素的组合,完全不是一回事儿!
另外要记住:整数数组索引返回的是原数组的副本,而切片返回的是视图——因为选取的元素可能是非连续的,没法用视图来关联原数组。
内容的提问来源于stack exchange,提问作者Bhuvesh Gupta

