-1

I am sorting a large multidimensional numpy array along an axis. After some computations I'd like to undo the sorting with the values themselves being different to when I did the initial sorting.

Initially I tried by simply reversing the sorting indices, but if the array was already sorted correctly in the first place this of course doesn't make any sense, see below code.

import numpy as np

array = np.random.rand(100,2,4)
array.out = array

arg = array.argsort(axis=1)
arg_rev = arg.argsort(axis=1)

# this solution is based on https://github.com/numpy/numpy/issues/4724

for i in range(0, array.shape[2]):
    tmp = array[:,:,i]
    array.out[:,:,i] = tmp[np.arange(np.shape(tmp)[0])[:, np.newaxis],  arg_ftc_rev[:,:,i]]



I would like to combine this solution with the one from undo or reverse argsort(), python without having to loop over an additional array index.

# ( a = np.random.randint(0,10,10)
# aa = np.argsort(a)
# aaa = np.argsort(aa) )
# e.g.
array.out[:,:,i] = tmp[np.arange(np.shape(tmp)[0])[:, np.newaxis],  arg_ftc[:,:,i][arg_ftc_rev[:,:,i]]

but this does not work, as it results in the wrong shape.

sophros
  • 14,672
  • 11
  • 46
  • 75
heffalump
  • 23
  • 4
  • "Undo sorting after changing values" is a pretty nebulous concept. Can you provide an example (with data) of what you would like to accomplish? – Scott Hunter Sep 13 '19 at 14:52
  • Use the `inverse_permutation` function at the end of [this answer](https://stackoverflow.com/a/25535723/1782792) to invert the result of argsort. – jdehesa Sep 13 '19 at 14:52
  • @jdehesa I tried ```python import numpy as np array = np.random.rand(100,2,4) arg = array.argsort(axis=1) x = inverse_permutation(arg) ``` but there is an error because it cannot broadcast. – heffalump Sep 13 '19 at 15:28
  • @ScottHunter I mean that the position of each element along the sorting axis should be as to begin with, however the values within these will have been modified. Simply sorting again is thus no option e.g. ```python x = [1, 3, 1, 6] x = sort(x) # [1, 1, 3, 6] x = x*2 # [2, 2, 6, 12] # undo sorting # [2, 6, 2, 12] ``` – heffalump Sep 14 '19 at 21:04

1 Answers1

0

It was a silly mistake

array.out[:,:,i] = tmp[np.arange(np.shape(tmp)[0])[:, np.newaxis], arg_ftc[:,:,i][arg_ftc_rev[:,:,i]]

needs to be

array.out[:,:,i] = tmp[np.arange(np.shape(tmp)[0])[:, np.newaxis], [arg_ftc_rev[:,:,i]]

heffalump
  • 23
  • 4