Ranking & Row Numbers

Python · GroupBy & SQL-Style Analytics

Theory

s.rank() gives each value its position in sorted order, with ascending=False for 'biggest = 1'. The method argument controls ties, matching SQL's ranking functions: method='min' gives tied values the same lowest rank and leaves a gap (1, 1, 3), like RANK(); method='dense' gives the same rank without gaps (1, 1, 2), like DENSE_RANK(); method='first' breaks ties by order of appearance (1, 2, 3), like ROW_NUMBER(). The default 'average' gives ties the mean rank (1.5, 1.5) and returns floats.

To rank within groups, rank on a groupby: df.groupby('city')['amount'].rank(method='dense', ascending=False) restarts at 1 for each city - RANK() OVER (PARTITION BY city ORDER BY amount DESC). For a plain ROW_NUMBER in a chosen order, sort first and then use df.groupby('city').cumcount() + 1, which numbers rows 1, 2, 3 within each group. rank(pct=True) gives percentile ranks between 0 and 1.

Why we use it

Leaderboards, top performers per region, 'second highest salary' and de-duplication by row number all need ranks. pandas reproduces SQL's RANK, DENSE_RANK and ROW_NUMBER with one call, including per partition.

When to use it

Choose method='min' for competition-style ranks, 'dense' for 'Nth highest' questions, 'first' or cumcount for unique row numbers. Rank within groups with groupby(...).rank(). For only the top n rows, nlargest or head after sorting is simpler.

How it works

  1. Need ranks or row numbers
  2. Pick the order: column and ascending=False for biggest first
  3. Should ties share a rank? Yes: method='min' or 'dense'. No: method='first' or cumcount()+1.
  4. Ranking within groups? Yes: df.groupby(key)[col].rank(...). No: Rank the whole column.
  5. Rank column (float - use astype(int) if needed)

Syntax

s.rank(method='min' | 'dense' | 'first' | 'average', ascending=False)
df.groupby('key')['col'].rank(method='dense', ascending=False)
df.sort_values([...]).groupby('key').cumcount() + 1

Example

df['rank'] = df.groupby('city')['amount'].rank(method='dense', ascending=False)
df['row_num'] = df.sort_values('amount', ascending=False).groupby('city').cumcount() + 1

Key points

Python topics

Getting Started

Variables & Data Types

Operators

Strings

Lists

Tuples

Sets

Dictionaries

Control Flow

Loops

Functions & OOP

Working with Data

Tooling & Errors

File Handling

Exception Handling

NumPy Library

Pandas Basics

Data Cleaning

Combining DataFrames (SQL Joins & Unions)

GroupBy & SQL-Style Analytics

Reshaping & Workflow

Data Visualization

Machine Learning (Scikit-Learn)

Advanced Python & AI

T
Tech Town
Log InSign Up Free
Home SQL Python DSA Power BI Snowflake Databricks Spark Gen AI Practice Problems Contest Blog

Python for Data Analysts

From basics to business insights — the complete step-by-step Python roadmap. Click any topic in the sidebar to open it right here.

{{ sectionCount }}
Sections
{{ topicCount }}
Topics
Free
Forever
Hands-on practice Practice Python Online 141 Python questions for data analysts — strings, records, dates, statistics and regex — with hidden tests and instant verdicts. Start practising →
Section {{ sec.num }}

{{ sec.label }}

Python  /  {{ current.sectionLabel }}  /  {{ current.name }}

{{ current.name }}

Theory

{{ current.def }}

Why we use it

{{ rich.why }}

When to use it

{{ rich.when }}

Diagram

{{ rich.dg.caption }}

{{ tb.title }}
{{ c.v }}
{{ rich.dg.op }}
➜
{{ rich.dg.output.title }}
{{ c.v }}
{{ nd.label }}
{{ nd.sub }}
{{ nd.label }}
{{ nd.sub }}
{{ rich.dg.left.title }}
{{ it }}
{{ rich.dg.right.title }}
{{ it }}
Flowchart — how it works
{{ nd.text }}
{{ nd.text }}
◇ {{ nd.text }}
Yes → {{ nd.yes }}
No → {{ nd.no }}
Syntax
{{ current.syntax }}
Example
{{ current.example }}
▶ Try It Live — runs real Python 3.12 in your browser (first run loads the engine)
{{ liveOutput }}
{{ liveError }}
Key Points — click to check off as you learn
  • {{ pt.mark }} {{ pt.text }}

Share this topic