Numpy的nonzero/flatnonzero索引顺序;布尔索引中返回元素的顺序

4 投票
1 回答
1454 浏览
提问于 2025-04-17 19:06

我在想,使用numpy.nonzero或numpy.flatnonzero时返回的索引顺序是怎样的。

我在文档里没找到相关的信息。文档里只说:

A[nonzero(flag)] == A[flag]

在大多数情况下,这些信息已经足够了,但有些时候你需要一个排序好的索引列表。那在一维情况下,返回的索引是保证排序的吗,还是我需要自己手动排序?(还有一个类似的问题是,当用布尔数组选择元素时(A[flag]),返回的元素顺序是否也必须一致,这在文档中有说明。)

举个例子:找出布尔数组flag中True元素之间的“间隙”:

flag=np.array([True,False,False,True],dtype=bool)
iflag=flatnonzero(flag)
gaps= iflag[1:] - iflag[:-1]

谢谢。

1 个回答

1

根据关于高级(或称“花哨”)整数索引的说明,A[nonzero(flag)] == A[flag]这个保证在一维情况下也意味着这些值是从小到大排序的。不过,在更高维度的情况下,结果虽然“排序了”,但结构可能和你想象的不太一样。

简单来说,给定一个一维的整数数组ind和一个要被索引的一维数组x,对于ind中所有有效的i,我们可以得到以下结果:

result[i] = x[ind[i]]

result的形状和ind一样,里面包含了x中由ind指定的索引的值。这意味着,如果x[flag]保持了x的原始顺序,并且x[nonzero(flag)]x[flag]是一样的,那么nonzero(flag)一定会产生有序的索引。

唯一需要注意的是,对于多维数组,索引是为每个被索引的维度存储为不同的数组。换句话说,

x[array([0, 1, 2]), array([0, 0, 0])]

等于

array([x[0, 0], x[1, 0], x[2, 0]])

这些值仍然是有序的,但每个维度被分开成了自己的数组。(因此你可以利用广播做一些有趣的事情;不过这超出了这个回答的范围。)

我觉得这个推理的唯一问题是——让我很惊讶的是——我找不到明确的说明来保证布尔索引会保持数组的原始顺序。不过,根据我的经验,我很确定它是这样的。更一般来说,如果x[[True, True, True]]返回的是x的反向版本,那简直是太不合理了。

撰写回答