NumPy: Unsort/undo a reverse/descending sort

烂漫一生 提交于 2019-12-08 10:36:10

问题


I can do an in-place reverse sort (descending sort) of a numpy array, but I also need to be able to unsort (undo) it later.

Given an unsorted example:

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

I tried:

i = a[::-1].argsort().argsort()  # BAD attempt to store original index
# i = array([3, 5, 0, 4, 1, 2])

a[::-1].sort()  # in-place reverse sort (works correctly)
# a= array([ 2,  1,  0, -1, -2, -3])

a = a[i]  # FAILS to restore original a
# a = array([-1, -3,  2, -2,  1,  0])

The above doesn't work. What would be the correct i that would work? Please assume the array is very large, so we don't want to make any unnecessary copies.


回答1:


The following idiom is cheaper (O(n)) than the second argsort (O(n log n)).

Example array x with sort order y

>>> x = np.random.random(10)
>>> y = x.argsort()[::-1]

Build inverse i

>>> i = np.empty_like(y)
>>> i[y] = np.arange(y.size)

Check:

>>> x
array([0.44257134, 0.573158  , 0.07762422, 0.31507426, 0.43414726,
       0.34923861, 0.22161337, 0.14090133, 0.66903264, 0.38888105])
>>> x[y]
array([0.66903264, 0.573158  , 0.44257134, 0.43414726, 0.38888105,
       0.34923861, 0.31507426, 0.22161337, 0.14090133, 0.07762422])
>>> x[y][i]
array([0.44257134, 0.573158  , 0.07762422, 0.31507426, 0.43414726,
       0.34923861, 0.22161337, 0.14090133, 0.66903264, 0.38888105])



回答2:


Given the unsorted example:

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

To unsort/undo its reverse/descending sort:

i = a.argsort()[::-1]
# i = array([4, 2, 5, 0, 1, 3])

a = a[i]  # descending sort using i
# a = array([ 2,  1,  0, -1, -2, -3])

a = a[i.argsort()]  # unsort using i
# a = array([-1, -2,  1, -3,  2,  0])

Credit: This answer is motivated by one on how to unsort a sort which doesn't concern with reverse sort.



来源:https://stackoverflow.com/questions/52825417/numpy-unsort-undo-a-reverse-descending-sort

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!