Numpy使用sort()反转数组后调用argsort()获取索引异常问题
问题原因
- 操作逻辑与接口设计误解:
np.argsort()的作用是返回将输入数组按升序从小到大排序后,每个排序后元素对应在原输入数组中的位置索引,和输入数组本身的排列顺序无关。
你示例中先对x做了就地升序排序,得到[3,5,6,6,8],此时数组本身已经是升序状态,调用np.argsort(x)自然返回[0,1,2,3,4]。后续你执行x[::-1].sort(),x[::-1]是原数组的视图,在视图上调用就地排序sort()相当于把反转后的视图做升序排序,最终原数组会被修改为降序的[8,6,6,5,3],此时调用np.argsort(x),会将这个降序数组按升序排列,得到的元素依次是3(原索引4)、5(原索引3)、6(原索引1)、6(原索引2)、8(原索引0),所以返回[4,3,1,2,0]是完全符合接口设计的正常结果,并非错误。 - 重复元素索引异常的原因:
np.argsort()默认使用快速排序算法,该算法属于不稳定排序,重复元素的相对顺序不会严格保留其在原数组中的出现顺序,因此你会看到两个值为6的元素索引顺序和你预期不一致的情况。
解决方法
- 若需要获取数组降序排序对应的索引,无需先修改原数组排列顺序,直接调用
np.argsort(-x)即可,也可以通过np.argsort(x)[::-1]反转升序索引得到降序索引,两种写法都不会修改原数组,逻辑更清晰。
示例代码:x = np.array([8,5,3,6,6]) # 获取升序排序索引 asc_idx = np.argsort(x) # 获取降序排序索引 desc_idx = np.argsort(-x) - 若需要保留重复元素在原数组中的出现顺序,给
np.argsort()指定稳定排序算法即可:stable_asc_idx = np.argsort(x, kind='stable') - 不要使用
x[::-1].sort()这种易混淆的写法实现数组降序,如果需要得到降序排列的新数组,推荐使用np.sort(x)[::-1],该方法返回新数组,不会修改原数组内容,避免后续索引逻辑混乱。
内容的提问来源于stack exchange,提问作者Mostafa Ramadan
相关产品推荐
相关产品推荐

