Assign a rank to each value in a column — the largest gets rank 1. By hand, each value's rank is 1 plus the count of values strictly greater than it. With pandas, Series.rank(ascending=False) does this in one call.

By hand

With pandas

df['score'].rank(ascending=False) assigns rank 1 to the largest value. rank() always returns float64; with distinct values the fractional part is always .0, so casting to int is safe.

naive.py
scores = [80, 55, 90, 70]
ranks = []
for s in scores:
    rank = 1
    for other in scores:
        if other > s:
            rank += 1
    ranks.append(rank)
print('RESULT:', ranks)
library.py
import pandas as pd
from dalib.display import set_display
set_display()

scores = [80, 55, 90, 70]
df = pd.DataFrame({'score': scores})
r = df['score'].rank(ascending=False)
ranks = [int(x) for x in r.tolist()]
print('index:', r.index.tolist())
print('values:', r.tolist())
print('dtype:', r.dtype)
print('RESULT:', ranks)
index: [0, 1, 2, 3]
values: [2.0, 4.0, 1.0, 3.0]
dtype: float64
RESULT: [2, 4, 1, 3]

Implementation notes

  • rank(ascending=True) (the default) assigns rank 1 to the smallest value. Pass ascending=False to rank largest-first, as done here — this matches the naive formula (1 + count of values greater).
  • With distinct values all tie methods agree. When ties exist, pandas offers: method='average' (default — mean of tied ranks), method='min' (lowest rank in the tie group), method='dense' (no gaps — [1,2,2,3] rather than [1,2,2,4]).
  • rank() always returns float64 regardless of the input dtype; cast with int() or .astype(int) only after confirming no NaN values.
  • Cross-reference: rank-assign (python-data-basics) for the pure-Python version.