Invert the scale of an array

Viewed 704

Say I have the following array:

x = np.array([3,7,1,2,6])

What is the simplest way to obtain the array with its scale say in the inverse way? So the minimum value would become the maximum, the maximum would become the minimum, and so on for the rest of the values.

Expected ouput:

array[3,1,7,6,2]

To clarify on what I want to obtain, say my original sequence is:

y = sorted(x)
#[1, 2, 3, 6, 7]

So the array sorted. If this was the case, the array that I would want is the array reversed, so [7, 6, 3, 2, 1]. I want to accomplish this with my current input.

Therefore, where I had the lowest value, 1 is now a 7, the second lowest vaule, 2 is now a 6, and so on.

4 Answers

Here is a numpy way:

np.sort(x)[::-1][np.argsort(np.argsort(x))]

Why this works: Suppose your list were already sorted, then you would just need to reverse it. Since the list isn't sorted we can first sort it, then reverse it, and then undo our sort.

Improvment: We really only need to compute argsort once. Then x can be sorted with this list and we can compute the inverse permutation to argsort(x) without another sort.

ax = np.argsort(x)
aax = np.zeros(len(ax),dtype='int')
aax[ax] = np.arange(len(ax),dtype='int')

x[ax[::-1]][aax]

If the input values are unique:

import numpy as np

x = np.array([3, 7, 1, 2, 6])

s = sorted(x)
lookup = {v: i for v, i in zip(s, reversed(s))}

result = np.array(list(map(lookup.get, x)))

print(result)

Output

[3 1 7 6 2]

If I understood correctly you want to assign to each value in the sorted order the value in the same position in the reverse sorted order.

here's my first thought:

In [13]: xr=np.zeros_like(x)

In [14]: g=0

In [15]: f=np.unique(sorted(x))

In [16]: for b in f:
             g-=1
             #for repeated values:
             for y in np.where(x==b)[0]:
                 xr[y]=f[g]
    ...:     
In [17]: xr
Out[17]: array([3, 1, 7, 6, 2])

Here is how I invert np array value (biggest value->smallest value, smallest value -> biggest) without sorting.

np_arr_inv = np_arr * -1 + np_arr.max()

I need to keep the order since it is image data.

FYI Numpy has a bit-wise inversion function here

Related