基本上你需要做一个argsort,你需要什么实现取决于你是想使用外部库(例如NumPy)还是你想保持纯Python而不依赖。
你需要问自己的问题是:你想要的
- 对数组/列表进行排序的索引
- 元素在排序数组/列表中的索引
不幸的是,问题中的示例并未明确说明所需的内容,因为两者都会给出相同的结果:
>>> arr = np.array([1, 2, 3, 100, 5])
>>> np.argsort(np.argsort(arr))
array([0, 1, 2, 4, 3], dtype=int64)
>>> np.argsort(arr)
array([0, 1, 2, 4, 3], dtype=int64)
选择argsort 实现
如果您可以使用 NumPy,您可以简单地使用函数 numpy.argsort 或方法 numpy.ndarray.argsort。
其他一些答案中已经提到了没有 NumPy 的实现,所以我将根据the benchmark answer here 回顾一下最快的解决方案
def argsort(l):
return sorted(range(len(l)), key=l.__getitem__)
获取对数组/列表进行排序的索引
要获得对数组/列表进行排序的索引,您只需在数组或列表上调用argsort。我在这里使用 NumPy 版本,但 Python 实现应该给出相同的结果
>>> arr = np.array([3, 1, 2, 4])
>>> np.argsort(arr)
array([1, 2, 0, 3], dtype=int64)
结果包含获取排序数组所需的索引。
由于排序后的数组将是[1, 2, 3, 4],因此 argsorted 数组包含原始中这些元素的索引。
- 最小值是
1,它位于原始索引1,因此结果的第一个元素是1。
-
2 在原始索引中位于索引2,因此结果的第二个元素是2。
-
3 在原始索引中位于索引0,因此结果的第三个元素是0。
- 最大值
4,它在原始索引中的索引3,所以结果的最后一个元素是3。
获取元素在排序数组/列表中的索引
在这种情况下,您需要申请argsort 两次:
>>> arr = np.array([3, 1, 2, 4])
>>> np.argsort(np.argsort(arr))
array([2, 0, 1, 3], dtype=int64)
在这种情况下:
- 原始的第一个元素是
3,这是第三大值,因此它在排序后的数组/列表中具有索引2,因此第一个元素是2。
- 原始的第二个元素是
1,这是最小值,因此它在排序后的数组/列表中有索引0,所以第二个元素是0。
- 原始的第三个元素是
2,这是第二小的值,因此它在排序后的数组/列表中有索引1,所以第三个元素是1。
- 原始的第四个元素是
4,这是最大值,所以它在排序的数组/列表中会有索引3,所以最后一个元素是3。