Rank with ties in python when tie breaker is random

Viewed 3813

In R , way to break ties randomly when using the rank function is simple:

rank(my_vec, ties.method = "random")

However, though both scipy (scipy.stats.rankdata) and pandas (pandas.Series.rank) have ranking functions, none of them suggest a method that break ties randomly. Is there a simple way to use a framework in python that has this feature? Given that list order has to remain the same.

1 Answers

Pandas' rank allows for these methods:

method : {'average', 'min', 'max', 'first', 'dense'}
    * average: average rank of group
    * min: lowest rank in group
    * max: highest rank in group
    * first: ranks assigned in order they appear in the array
    * dense: like 'min', but rank always increases by 1 between groups

To "simply" accomplish your goal we can use 'first' after having randomized the Series.

Assume my series is named my_vec

my_vec.sample(frac=1).rank(method='first')

You can then put it back in the same order it was with

my_vec.sample(frac=1).rank(method='first').reindex_like(my_vec)

Example Runs

my_vec = pd.Series([1, 2, 3, 1, 2, 3])

Trial 1

my_vec.sample(frac=1).rank(method='first').reindex_like(my_vec)

0    2.0  <- I expect this and
1    4.0
2    6.0
3    1.0  <- this to be first ranked
4    3.0
5    5.0
dtype: float64

Trial 2

my_vec.sample(frac=1).rank(method='first').reindex_like(my_vec)

0    1.0  <- Still first ranked
1    3.0
2    6.0
3    2.0  <- but order has switched
4    4.0
5    5.0
dtype: float64
Related