NumPy:高效地在已排序的数组中查找索引

5
我想对一个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个回答

4
你可以在列表上两次使用argsort。 一开始这个方法似乎有点令人困惑,但是如果你花一些时间思考它,它就开始变得有意义了。
a = np.array([1, 4, 2, 3])
argSorted = np.argsort(a) # [0, 2, 3, 1]
invArgSorted = np.argsort(argSorted) # [0, 3, 1, 2]

1
你是否忘记将某些东西传递给 argsort 的第二次调用了?通过解释它的工作原理以及为什么它有意义,你可以改进答案 :) - MB-F
我和其他人已经建议使用双重argsort,但没有详细的解释。https://dev59.com/urHma4cB1Zd3GeqPLGkz - hpaulj

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]

很好,谢谢 :) - lhk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接