3

I have seen answers to the question:
Is it possible to arrange a numpy array (or python list) by using the indexes of the elements in decreasing order? (eg. Finding the Index of N biggest elements in Python Array / List Efficiently)

A very concise answer seems to be (from above link):

L = array([4, 1, 0, 8, 5, 2])
sorted(range(len(L)), key=lambda i:L[i])

This gives the position (in the original array) of the sorted elements.

8 --> 3
5 --> 4
4 --> 0
2 --> 5
1 --> 1
0 --> 2

So the answer is:

[3, 4, 0, 5, 1, 2]

What I am after is the position (in the sorted array) of the elements:

L = array([4, 1, 0, 8, 5, 2])

8 --> 0
5 --> 1
4 --> 2
2 --> 3
1 --> 4
0 --> 5

So I want :

[2, 4, 5, 0, 1, 3] 

I realise I could take the answer from the first example, and use that to get what I want (with a bit more fiddling) but is there a short cut?

Efficiency is not a concern. I just need something that gives me the answer.

1
  • Thanks guys for your responses. I like the use of the lambda expression twice to get what I what. Now is someone can just explain (in really simple terms for a tyro) how that line of code actually operates I will be grateful! Commented Dec 18, 2013 at 23:08

3 Answers 3

3

EDIT when I first read the question, I thought you were looking for numpy.argsort.

Having read it again, I realized I misread.

scipy.stats.rankdata is what you're looking for (offset by 1, and reversed)

(scipy.stats.rankdata([4, 1, 0, 8, 5, 2])-1)[::-1]
=> array([ 2.,  4.,  5.,  0.,  1.,  3.])

(Original wrong answer, referring to argsort:)

from numpy import array, argsort
L = array([4, 1, 0, 8, 5, 2])
argsort(L)
=> array([2, 1, 5, 0, 4, 3])
Sign up to request clarification or add additional context in comments.

4 Comments

Isn't this giving the wrong answer? He wants [2,4,5,0,1,3] as the answer?
This does the thing from the first version (but in reverse), which he doesn't want.
@PeterdeRivaz right, I misread the question. I fixed my answer now.
You might want to add the method='ordinal' flag.
0

You can simply use your technique twice to get the indices in the sorted list:

A=[4, 1, 0, 8, 5, 2]
B=sorted(range(len(A)),key=lambda x:A[x],reverse=True)
C=sorted(range(len(A)),key=lambda x:B[x])
print C

prints

[2, 4, 5, 0, 1, 3]

Explanation

The idea is that the first iteration produces a list:

B = [3, 4, 0, 5, 1, 2]

giving the locations in the original list of the sorted sequence.

In other words, A[3]=8 is the largest element in the original list, A[4]=5 is the next largest, etc.

The second stage then sorts these indices in B back into the order 0,1,2,3,4,5 and produces C which contains the index in the list B.

It may help to think of B as sorting the list into descending order, and C as reversing the sort back into the original unsorted order, while keeping track of the indices in the sorted list.

2 Comments

Maybe I spoke too soon? Ok with: A=[4, 1, 0, 8, 5, 2] Tried A=[14, 15, 30, 18, 11, 21]
@RustyC You are quite right, I've edited the answer to behave better
-1

are you using numpy? if so, use numpy.argsort

import numpy as np
fakedata = np.array([40,20,60,50,10,20,80,30,50,40])
sorted_index = np.argsort(fakedata)
print(sorted_index)
print(fakedata[sorted_index])
[4 1 5 7 0 9 3 8 2 6] # sorted index
[10 20 20 30 40 40 50 50 60 80] # values selected by the sorted index

1 Comment

This is an answer to the first part of my question - the one that has already been answered elsewhere. I want: For each element in the original list give me its position in the sorted list. Not: For each element in the sorted list give me its position in the original list.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.