It seems you are trying to trace back the elements positions in the sorted order.
Approach #1 : One way to do so would be to use argsort
twice, like so -
a.argsort(1).argsort(1)+1
Approach #2 : Efficient method inspired by this post
-
def argsort_unique2D(idx):
m,n = idx.shape
sidx = np.empty((m,n),dtype=int)
sidx[np.arange(m)[:,None], idx] = np.arange(n)
return sidx
out = argsort_unique2D(a.argsort(1))+1
Sample run -
In [42]: a
Out[42]:
array([[15, 12, 10, 8, 7],
[ 7, 8, 4, 3, 1],
[ 8, 5, 9, 12, 4],
[ 6, 10, 14, 7, 5]])
In [43]: a.argsort(1).argsort(1)+1
Out[43]:
array([[5, 4, 3, 2, 1],
[4, 5, 3, 2, 1],
[3, 2, 4, 5, 1],
[2, 4, 5, 3, 1]])
In [71]: argsort_unique2D(a.argsort(1))+1
Out[71]:
array([[5, 4, 3, 2, 1],
[4, 5, 3, 2, 1],
[3, 2, 4, 5, 1],
[2, 4, 5, 3, 1]])
Runtime test -
In [76]: a = np.random.rand(100,10000)
In [77]: %timeit a.argsort(1).argsort(1)+1
10 loops, best of 3: 115 ms per loop
In [78]: %timeit argsort_unique2D(a.argsort(1))+1
10 loops, best of 3: 67.8 ms per loop