Add sequential number to a groupby().head(n) expression in Pandas

Viewed 39

I have an expression in Pandas where I sort the top three values by country:

Country              | Value
---------------------|------
Germany              | 102.1
Germany              | 90.3
Germany              | 44.6
Switzerland          | 59.9
Switzerland          | 35.3
Switzerland          | 21.6

...and so on

which I obtained using df.groupby("Country").head(3)[["Country", "Value"]]. Now, I'd like to append a third column that associates the rank within the country to the value:

Country              | Value  | Rank
---------------------|--------|------
Germany              | 102.1  | 1
Germany              | 90.3   | 2
Germany              | 44.6   | 3
Switzerland          | 59.9   | 1
Switzerland          | 35.3   | 2
Switzerland          | 21.6   | 3

...and so on

How would I best go about doing this?

1 Answers

I believe you need GroupBy.rank and method='dense' for rank always increases by 1 between groups by sorted values of Value column with converting to integers:

df['Rank'] = df.groupby("Country")["Value"].rank(method='dense', ascending=False).astype(int)
print (df)
       Country  Value  Rank
0      Germany  102.1     1
1      Germany   90.3     2
2      Germany   44.6     3
3  Switzerland   59.9     1
4  Switzerland   35.3     2
5  Switzerland   21.6     3

If need counter then is better use GroupBy.cumcount:

df['Rank1'] = df.groupby("Country").cumcount() + 1

Difference is best seen in changed data:

print (df)
       Country  Value
0      Germany   90.3 second largest per group - 2
1      Germany  102.1 largest per group - 1
2      Germany   44.6 third largest per group - 3
3  Switzerland   21.6
4  Switzerland   35.3
5  Switzerland   59.9

df['Rank'] = df.groupby("Country")["Value"].rank(method='dense', ascending=False).astype(int)
df['Rank1'] = df.groupby("Country").cumcount() + 1

print (df)
       Country  Value  Rank  Rank1
0      Germany   90.3     2      1
1      Germany  102.1     1      2
2      Germany   44.6     3      3
3  Switzerland   21.6     3      1
4  Switzerland   35.3     2      2
5  Switzerland   59.9     1      3
Related