为什么使用np.argwhere返回的索引给二维数组赋值会出现越界错误
NumPy数组索引逻辑差异说明
核心背景
np.argwhere(obj_img==0)返回的是形状为(N, 2)的二维整数数组,其中N是符合obj_img==0条件的元素总数,每一行的格式为[行索引, 列索引]。
两种索引方式的处理逻辑
1. obj_img[ndxs]的处理逻辑
对于二维数组obj_img,如果仅传入一个索引参数,NumPy会默认该参数是轴0(行维度)的索引数组,剩余维度自动全量选取,等价于obj_img[ndxs, :]。
此时你传入的ndxs是形状为(N, 2)的二维数组,NumPy会把数组内的每一个值(不管是第一列的行索引还是第二列的列索引)都当作轴0的索引值去取值。如果你的obj_img轴0长度为22,合法索引范围是0~21,而ndxs第二列的列索引最大值可能达到22,就会触发IndexError: index 22 is out of bounds for axis 0 with size 22的报错。
举个最小示例验证:
import numpy as np # 构造2行3列的测试数组,轴0最大索引为1,轴1最大索引为2 obj_img = np.array([[0,1,0],[2,0,3]]) ndxs = np.argwhere(obj_img==0) print(ndxs) # 输出结果: # [[0 0] # [0 2] # [1 1]] # 执行obj_img[ndxs]会尝试用2作为轴0的索引,直接触发越界报错
2. obj_img[ndxs[:,0], ndxs[:,1]]的处理逻辑
当你给二维数组的两个轴分别传入长度相同的一维数组时,NumPy会触发高级索引的配对规则:将两个数组相同位置的元素配对,作为对应轴的索引取值。
比如ndxs[:,0]是长度为N的行索引数组,ndxs[:,1]是长度为N的列索引数组,NumPy会依次取(ndxs[0,0], ndxs[0,1])、(ndxs[1,0], ndxs[1,1])……(ndxs[N-1,0], ndxs[N-1,1])位置的元素,刚好就是你需要的所有值为0的位置,因此可以正常赋值。
如果想简化写法,也可以直接用obj_img[tuple(ndxs.T)] = np.nan,效果和上述写法完全一致。
内容的提问来源于stack exchange,提问作者jrive
相关产品推荐
相关产品推荐

