2

I have a two-dimensional numpy array and I am wondering how I can create a new two-dimensional numpy array represent the ranking of the values based on all items in the original 2d array.

I would like to use the following array :

anArray = [[ 18.5,  25.9,   7.4,  11.1,  11.1]
           [ 33.3,  37. ,  14.8,  22.2,  25.9]
           [ 29.6,  29.6,  11.1,  14.8,  11.1]
           [ 25.9,  25.9,  14.8,  14.8,  11.1]
           [ 29.6,  25.9,  14.8,  11.1,   7.4]]

to create a new rank ordered array [based on all values and having same rank for multiple numbers] :

anOrder = [[ 6,  4,  9,  8,  8]
           [ 2,  1,  7,  5,  4]
           [ 3,  3,  8,  7,  8]
           [ 4,  4,  7,  7,  8]
           [ 3,  4,  7,  8,  9]]

Thank you.

2 Answers 2

5

You can use scipy.stats.rankdata with method='dense'. It ranks the values of the flattened input, so you'll have to restore the shape of the array returned by rankdata.

For example,

In [21]: anArray
Out[21]: 
[[18.5, 25.9, 7.4, 11.1, 11.1],
 [33.3, 37.0, 14.8, 22.2, 25.9],
 [29.6, 29.6, 11.1, 14.8, 11.1],
 [25.9, 25.9, 14.8, 14.8, 11.1],
 [29.6, 25.9, 14.8, 11.1, 7.4]]

In [22]: a = np.array(anArray)

In [23]: r = rankdata(a, method='dense').reshape(a.shape)

In [24]: ranks = (r.max()+1) - r

In [25]: ranks
Out[25]: 
array([[6, 4, 9, 8, 8],
       [2, 1, 7, 5, 4],
       [3, 3, 8, 7, 8],
       [4, 4, 7, 7, 8],
       [3, 4, 7, 8, 9]])

Note that rankdata ranks from low to high, starting with 0, so the ranks r are reversed and set to start at 1 with the line ranks = (r.max()+1) - r.

Sign up to request clarification or add additional context in comments.

Comments

3

That's a routine work for np.unique with its optional argument return_inverse that tags each element based on the uniqueness among other elements, like so -

_,id = np.unique(anArray,return_inverse=True)
out = (id.max() - id + 1).reshape(anArray.shape)

Sample run -

In [17]: anArray
Out[17]: 
array([[ 18.5,  25.9,   7.4,  11.1,  11.1],
       [ 33.3,  37. ,  14.8,  22.2,  25.9],
       [ 29.6,  29.6,  11.1,  14.8,  11.1],
       [ 25.9,  25.9,  14.8,  14.8,  11.1],
       [ 29.6,  25.9,  14.8,  11.1,   7.4]])

In [18]: _,id = np.unique(anArray,return_inverse=True)

In [19]: (id.max() - id + 1).reshape(anArray.shape)
Out[19]: 
array([[6, 4, 9, 8, 8],
       [2, 1, 7, 5, 4],
       [3, 3, 8, 7, 8],
       [4, 4, 7, 7, 8],
       [3, 4, 7, 8, 9]])

Comments

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.