Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can numpy's argsort give equal element the same rank?

I want to get the rank of each element, so I use argsort in numpy:

np.argsort(np.array((1,1,1,2,2,3,3,3,3)))
array([0, 1, 2, 3, 4, 5, 6, 7, 8])

it give the same element the different rank, can I get the same rank like:

array([0, 0, 0, 3, 3, 5, 5, 5, 5])
like image 995
maple Avatar asked Aug 20 '16 22:08

maple


People also ask

Is NumPy Argsort stable?

NumPy's np. argsort is able to do stable sorting through passing kind = 'stable' argument.

How does NP Argsort work?

argsort() function is used to perform an indirect sort along the given axis using the algorithm specified by the kind keyword. It returns an array of indices of the same shape as arr that would sort the array.

What does NP Argsort return?

np. argsort returns the index of the sorted array given by the 'kind' (which specifies the type of sorting algorithm).

What does Argsort mean?

Start Learning. In Python, the NumPy library has a function called argsort() , which computes the indirect sorting of an array. It returns an array of indices along the given axis of the same shape as the input array, in sorted order.

How to rank values using argsort NumPy function?

See how to rank values using the argsort Numpy function. import numpy as np my_array = np.array ( [ [1, 56, 55, 15], [5, 4, 33, 53], [3, 6, 7, 19]]) sorted_array = np.argsort (my_array, axis=0) print (f"These are ranks of array values: {sorted_array}") As you can see, there are ranks given for the values in your array.

How do I get the rank of an array in NumPy?

The numpy.argsort () method is called by the array and returns the rank of each element inside the array in the form of another array. import numpy as np array = np.array([1,8,5,7,9]) temp = array.argsort() ranks = np.empty_like(temp) ranks[temp] = np.arange(len(array)) print(array) print(ranks)

How do you sort an array in NumPy?

numpy.argsort() function is used to perform an indirect sort along the given axis using the algorithm specified by the kind keyword. It returns an array of indices of the same shape as arr that that would sort the array. Syntax : numpy.argsort(arr, axis=-1, kind=’quicksort’, order=None) Parameters : arr : [array_like] Input array.

How to assign a rank to each element in an array?

After that, we created another array, ranks, that contains the rank of each element in the array. We then assigned the rank of each element inside the array to each element of the ranks with ranks [temp] = np.arange (len (array)).


2 Answers

If you don't mind a dependency on scipy, you can use scipy.stats.rankdata, with method='min':

In [14]: a
Out[14]: array([1, 1, 1, 2, 2, 3, 3, 3, 3])

In [15]: from scipy.stats import rankdata

In [16]: rankdata(a, method='min')
Out[16]: array([1, 1, 1, 4, 4, 6, 6, 6, 6])

Note that rankdata starts the ranks at 1. To start at 0, subtract 1 from the result:

In [17]: rankdata(a, method='min') - 1
Out[17]: array([0, 0, 0, 3, 3, 5, 5, 5, 5])

If you don't want the scipy dependency, you can use numpy.unique to compute the ranking. Here's a function that computes the same result as rankdata(x, method='min') - 1:

import numpy as np

def rankmin(x):
    u, inv, counts = np.unique(x, return_inverse=True, return_counts=True)
    csum = np.zeros_like(counts)
    csum[1:] = counts[:-1].cumsum()
    return csum[inv]

For example,

In [137]: x = np.array([60, 10, 0, 30, 20, 40, 50])

In [138]: rankdata(x, method='min') - 1
Out[138]: array([6, 1, 0, 3, 2, 4, 5])

In [139]: rankmin(x)
Out[139]: array([6, 1, 0, 3, 2, 4, 5])

In [140]: a = np.array([1,1,1,2,2,3,3,3,3])

In [141]: rankdata(a, method='min') - 1
Out[141]: array([0, 0, 0, 3, 3, 5, 5, 5, 5])

In [142]: rankmin(a)
Out[142]: array([0, 0, 0, 3, 3, 5, 5, 5, 5])

By the way, a single call to argsort() does not give ranks. You can find an assortment of approaches to ranking in the question Rank items in an array using Python/NumPy, including how to do it using argsort().

like image 128
Warren Weckesser Avatar answered Oct 05 '22 18:10

Warren Weckesser


Alternatively, pandas series has a rank method which does what you need with the min method:

import pandas as pd
pd.Series((1,1,1,2,2,3,3,3,3)).rank(method="min")

# 0    1
# 1    1
# 2    1
# 3    4
# 4    4
# 5    6
# 6    6
# 7    6
# 8    6
# dtype: float64
like image 26
Psidom Avatar answered Oct 05 '22 16:10

Psidom