Rank array of tuples

I have an array

array = [('item1',90),('item2',76),('item3',83),('item4',90)]

      

and I would like to rate it as

ranking = [(0,'item1'),(0,'item4'),(2,'item3'),(3,'item2')] // (1)

      

This is what I have done so far using ranking :

from ranking import *

>>> array.sort(key=lambda x: x[1],reverse = True)
>>> print [i for i in list(Ranking([i[1] for i in array]))]

      

This is what I get:

[(0, 90), (0, 90), (2, 83), (3, 76)] // (2)

      

Can anyone help me get from (2) to (1)? I don't need to use ranking

. I accept any other decision.

+3


source to share


5 answers


array = [('item1',90),('item2',76),('item3',83),('item4',90)]
srt = sorted(array,key=lambda x: x[1], reverse=True)
rankings = []
rank = 0
from itertools import groupby
for k,v in groupby(srt,lambda x: x[1]): # group by score
    grp = [(rank,tup[0]) for tup in v] # get item tup[0] and put it in a tuple with the rank
    rankings += grp
    rank += len(grp) # increase rank for next grouping
print(rankings)
[(0, 'item1'), (0, 'item4'), (2, 'item3'), (3, 'item2')]

      



+2


source


array = [('item1',90),('item2',76),('item3',83),('item4',90)]

def s(t):
    return t[1]

array.sort(reverse = True, key = s)

def rank(array):
    res = []
    for index, tup in enumerate(array):
        if index == 0:
            res.append(tuple([ index, tup[0]]))
        elif tup[1] == array[index -1][1]:
            res.append(tuple([index -1, tup[0]]))
        else:
            res.append(tuple([index , tup[0]]))
    return res
r = rank(array)
print r

      

Output - [(0, 'item1'), (0, 'item4'), (2, 'item3'), (3, 'item2')]



This can be a very long solution, but I hope it works fine

+1


source


You can use Pandas DataFrame for this. I would recommend this solution as it is very semantically intended for the purposes you want to put it for:

import pandas as pd
df = pd.DataFrame.from_records([('item1',90),('item2',76),
                                ('item3',83),('item4',90)])

      

Here's the raw dataframe before we process it:

>>> df
       0   1
0  item1  90
1  item2  76
2  item3  83
3  item4  90

      

Now we will select column 1 and break it down in descending order, and then add the rank back to the framework (using the min method):

>>> df['rank'] = df[1].rank(method='min', ascending=False)
>>> df
       0   1  rank
0  item1  90     1
1  item2  76     4
2  item3  83     3
3  item4  90     1

      

We now convert our lookup columns back to a list of tuples excluding the index:

>>> l = list(df[[0, 'rank']].to_records(index=False))
>>> l
[('item1', 1.0), ('item2', 4.0), ('item3', 3.0), ('item4', 1.0)]

      

We can get it into the desired state with a list:

>>> l2 = [(i, int(j-1)) for i, j in l]
>>> l2
[('item1', 0), ('item2', 3), ('item3', 2), ('item4', 0)]

      

+1


source


I don't have a ranking so I can't test it, but the documentation says Ranking () supports passing a key function to select values ​​from a list.

I suggest trying something like this:

print Ranking(array, key=lambda x: x[1], reverse=True)

      

0


source


array = [('item1',90),('item2',76),('item3',83),('item4',90)]
values = sorted(v for k, v in array)
d = dict(zip(values, range(len(values)-1, -1, -1)))
print sorted(( (d[i],item) for (item, i) in array ))

      

This results in the output:

[(0, 'item1'), (0, 'item4'), (2, 'item3'), (3, 'item2')]

      

How it works

values

contains a sorted list of values:

[76, 83, 90, 90]

      

We then create a dictionary d

to rank their order. d

:

{76: 3, 83: 2, 90: 0}

      

0


source







All Articles