numpy:在排序数组中查找索引(有效方式)

时间:2019-01-31 11:26:22

标签: python arrays numpy

我想对一个numpy数组进行排序,并找出每个元素的去向。

numpy.argsort会告诉我排序数组中的每个索引,未排序数组中的哪个索引去了。我正在寻找相反的东西:对于未排序数组中的每个索引,它在已排序数组中的位置。

a = np.array([1, 4, 2, 3])

# a sorted is [1,2,3,4]
# the 1 goes to index 0
# the 4 goes to index 3
# the 2 goes to index 1
# the 3 goes to index 2

# desired output
[0, 3, 1, 2]

# for comparison, argsort output
[0, 2, 3, 1]

一个简单的解决方案使用numpy.searchsorted

np.searchsorted(np.sort(a), a)
# produces [0, 3, 1, 2]

我对此解决方案不满意,因为它似乎效率很低。它通过两个单独的步骤进行排序和搜索。

对于带有重复项的数组,此奇特索引失败,请查看:

a = np.array([1, 4, 2, 3, 5])
print(np.argsort(a)[np.argsort(a)])
print(np.searchsorted(np.sort(a),a))


a = np.array([1, 4, 2, 3, 5, 2])
print(np.argsort(a)[np.argsort(a)])
print(np.searchsorted(np.sort(a),a))

2 个答案:

答案 0 :(得分:2)

您只需要invert the permutation对数组进行排序即可。如链接的问题所示,您可以这样做:

import numpy as np

def sorted_position(array):
    a = np.argsort(array)
    a[a.copy()] = np.arange(len(a))
    return a

print(sorted_position([0.1, 0.2, 0.0, 0.5, 0.8, 0.4, 0.7, 0.3, 0.9, 0.6]))
# [1 2 0 5 8 4 7 3 9 6]

答案 1 :(得分:1)

您可以在列表中两次使用argsort。 起初,这种方法看起来有点混乱,但是如果您考虑一会儿,它就会变得有意义。

a = np.array([1, 4, 2, 3])
argSorted = np.argsort(a) # [0, 2, 3, 1]
invArgSorted = np.argsort(argSorted) # [0, 3, 1, 2]