含重复元素的numpy.argsort如何实现确定性排序?
让NumPy argsort对重复元素返回确定性结果
当NumPy的argsort处理包含重复元素的数组时,由于底层排序算法的非稳定性(不同环境或版本可能采用不同实现),相同值元素的索引顺序可能出现变化,这并非Bug,而是算法的特性。要让结果完全确定,比如让相同值的元素按原索引从小到大排列,可以用以下两种方法:
方法1:使用np.lexsort实现多键排序
lexsort支持按多个键排序,我们可以先按数组值排序,再按元素的原索引排序,确保相同值的元素保留索引小的在前:
import numpy as np arr = np.array([4, 2, 0, 6, 4, 3, 7, 6, 5, 7, 1, 2]) # lexsort的排序键优先级从后往前,这里先按arr的值排序,再按索引排序 sorted_indices = np.lexsort((np.arange(len(arr)), arr)) print(sorted_indices)
执行后会稳定输出[ 2 10 1 11 5 0 4 8 3 7 6 9],相同值的元素索引不会乱序。
方法2:结合Python内置sorted函数
Python内置的sorted是稳定排序,我们可以构造包含索引和值的元组,指定排序键为(值, 索引),再提取索引:
import numpy as np arr = np.array([4, 2, 0, 6, 4, 3, 7, 6, 5, 7, 1, 2]) # 按(值, 索引)排序,提取结果中的索引 sorted_indices = np.array([idx for idx, val in sorted(enumerate(arr), key=lambda x: (x[1], x[0]))]) print(sorted_indices)
这种方法逻辑直观,同样能得到完全确定的排序索引结果。
内容的提问来源于stack exchange,提问作者Nico Schlömer
相关产品推荐
相关产品推荐

