Sort and Rank Your Data
Sort and Rank Your Data Easily — Data Analysis with Python.
Focus: sort and rank your data easily
You have a clean dataset, every column is in place, and the numbers look right — but the story it tells is hidden until you order it. Sorting and ranking are the quiet heroes of data analysis: they turn a random jumble of rows into a clear narrative of best-sellers, top performers, or fastest-growing trends. If you've ever tried to find the top 5 customers in a spreadsheet by hand or struggled to explain why a ranking column matters, this lesson is your shortcut. By the end, you'll sort and rank your data easily with pandas — and know exactly when to use each tool.
The problem this lesson solves
Raw data is almost never in the order you need it. Say you export a list of sales transactions: the rows arrive in chronological order, but you need to know which product earned the most last quarter. Or you have a DataFrame of student scores and want to assign positions — first, second, third — for a leaderboard. Without sorting, you're scrolling through thousands of rows; without ranking, you're manually counting who's ahead.
Sorting and ranking are distinct operations: - Sorting reorders the rows based on one or more columns — a complete rearrangement of the data. - Ranking adds a new column that assigns a numeric position (1, 2, 3…) to each row based on its value, without changing the original order.
Many beginners conflate the two. They sort when they only need a rank, or rank when they need a clean top-10 list. This lessons than clears the confusion and gives you both tools in your pandas toolkit.
Core concept / mental model
Think of sorting as rearranging books on a shelf by height — the physical order changes. Ranking is putting numbered stickers on each book that tell you its size rank, while the shelf order stays the same.
In pandas, you work with two main methods, both on a Series or DataFrame:
sort_values()— reorders rows by one or more columns. You decide ascending or descending, and how to handle missing values.rank()— creates a new Series of ranks (1 = smallest or largest, depending on methods) that keeps the original row order intact.
A mental model to remember:
sort_values()changes the order of rows.rank()changes the data itself (adds a new column) but leaves row order untouched.
Think of sort_values() as 'show me the data in this sequence' and rank() as 'tell me where each item stands'.
How it works step by step
Step 1: Sort by a single column
The simplest case: sort a DataFrame by one column using sort_values().
import pandas as pd
sales = pd.DataFrame({
'product': ['A', 'B', 'C', 'D'],
'revenue': [250, 150, 400, 100]
})
# Sort by revenue, ascending (smallest first)
sorted_asc = sales.sort_values('revenue')
print(sorted_asc)
Output:
product revenue
3 D 100
1 B 150
0 A 250
2 C 400
Notice the index is preserved — rows are moved, but their original labels stay. If you want a fresh 0-based index, use reset_index(drop=True).
Step 2: Sort by multiple columns
Real data often needs a secondary tie-breaker. For example, sort by category and then by revenue within each category.
sales['category'] = ['X', 'Y', 'X', 'Y']
sorted_multi = sales.sort_values(['category', 'revenue'], ascending=[True, False])
print(sorted_multi)
The list of column names determines priority; the list of booleans controls direction for each column. Here, category 'X' comes first, and within X, revenue drops from 250 to 400? No — wait, for X only A (250) exists, so it's fine. For Y, B (150) and D (100), descending means B before D.
Output (simplified):
product revenue category
0 A 250 X
1 B 150 Y
3 D 100 Y
Step 3: Rank a column
Now assign a rank to each row based on revenue, without changing the row order.
sales['rank'] = sales['revenue'].rank(method='min', ascending=False)
print(sales)
Output:
product revenue category rank
0 A 250 X 2.0
1 B 150 Y 3.0
2 C 400 X 1.0
3 D 100 Y 4.0
Ranks are floats by default — you can convert with .astype(int) if you want integers.
Hands-on walkthrough
Let's put sorting and ranking to work in a realistic scenario: analyzing a small e-commerce dataset. We'll load data, sort by multiple columns, and create ranks for top products.
import pandas as pd
# Sample data: orders with product, region, quantity
orders = pd.DataFrame({
'order_id': [101, 102, 103, 104, 105],
'product': ['Widget', 'Gadget', 'Widget', 'Gizmo', 'Gadget'],
'region': ['North', 'North', 'South', 'North', 'South'],
'quantity': [5, 3, 8, 2, 7]
})
# Sort by region (alphabetical) and then by quantity (highest first)
sorted_orders = orders.sort_values(['region', 'quantity'], ascending=[True, False])
print("Sorted orders:")
print(sorted_orders)
# Rank orders within each region by quantity (1 = most)
orders['region_rank'] = orders.groupby('region')['quantity'].rank(ascending=False, method='min')
print("\nWith region rank:")
print(orders)
Output:
Sorted orders:
order_id product region quantity
0 101 Widget North 5
3 104 Gizmo North 2
1 102 Gadget North 3 # wait, this is wrong because we had 3 North rows
Wait — the output above is inconsistent. Let's correct: the data has three North rows (101, 102, 104) and two South (103, 105). After sorting, the North block starts with quantity 5 (101), then 3 (102), then 2 (104). South block: quantity 8 (103) and 7 (105). The printed output would show rows in that order. Below is the corrected output.
order_id product region quantity
0 101 Widget North 5
1 102 Gadget North 3
3 104 Gizmo North 2
2 103 Widget South 8
4 105 Gadget South 7
The rank column shows 1, 2, 3 for North and 1, 2 for South.
This exercise shows both tools in action: sorting reorders rows for presentation, ranking creates a new interpretable column that you can use for filtering, grouping, or further analysis.
Compare options / when to choose what
| Scenario | Use sort_values() |
Use rank() |
|---|---|---|
| Top 10 list | ✅ Yes | ❌ No |
| Leaderboard positions | ❌ No | ✅ Yes |
| Reorder DataFrame permanently | ✅ Yes | ❌ No |
| Keep original order but show rank | ❌ No | ✅ Yes |
| Sort by multiple columns | ✅ Yes (by list) |
❌ No |
| Rank within groups | ❌ No | ✅ Yes (groupby + rank) |
Key differences:
- sort_values() changes row order; rank() adds a column.
- Sorting can be multi-column; ranking is always based on a single column (with grouping for subgroups).
- Ranking handles ties with methods like average, min, max, first; sorting just repeats equal values.
When to use what: - Use sorting when you need to display data in a meaningful order — like a table for a report. - Use ranking when you need to compute positions inside the data — like assigning medals to athletes.
Variations
sort_index()— sorts by the index, not a column. Useful when you've reset indices and want chronological order back.nlargest()/nsmallest()— return the top N rows without sorting the whole DataFrame. Efficient for large data.rank(method='first')— for ties, gives ranks in order of appearance, giving distinct integers (useful for deterministic wins).
Troubleshooting & edge cases
Problem 1: Sorting changes the original DataFrame?
By default, sort_values() returns a new DataFrame and does not modify the original. If you want to keep the sorted version, assign it back:
df = df.sort_values('col') # correct
df.sort_values('col') # wrong - result is discarded
Problem 2: Ranks are floats — I want integers
Ranks are float by default to handle averages. Convert with:
df['rank'] = df['rank'].astype(int)
But be careful with ties — converting to int loses the decimal (e.g., 2.5 becomes 2). Better to use method='min' for integer-like ranks.
Problem 3: Missing values (NaN)
- Sorting:
na_positionparameter controls where NaNs go —'last'(default) or'first'. - Ranking: NaN values get NaN rank by default. If you want them treated as smallest, use
method='min'but they'll still be NaN; consider filling them first.
Problem 4: Sorting by a column with mixed types
You get a TypeError if the column has both strings and numbers. Fix by converting the column to a consistent type first:
df['col'] = df['col'].astype(str)
Problem 5: Ranking within groups gives unexpected order
The rank() method is not aware of group order unless you use groupby() as shown earlier. If you call df['rank'] = df['value'].rank() without grouping, you rank across the whole DataFrame, not per group.
What you learned & what's next
You now have two powerful tools to bring order to chaos:
- sort_values() to reorder rows by one or more columns, ascending or descending, with control over missing values.
- rank() to assign numerical positions to each row, with flexible tie-breaking methods and group support.
You can explain the core idea behind sorting and ranking, and you've completed a practical exercise that combined both. You're ready to move to the next step in your data analysis journey — perhaps aggregating and summarizing that sorted and ranked data to draw deeper insights.
Practice recap
Try this mini-exercise on your own: load a small dataset (or use the orders example above), sort it by region and quantity descending, then add a ranking column that ranks orders within each region by quantity. Verify your output makes sense — the highest quantity in each region should have rank 1. Then experiment with the method parameter to see how ties are handled.
Common mistakes
- Forgetting to assign the result of
sort_values()back to the DataFrame, so the original remains unsorted. - Using
rank()without specifyingascending=Falsewhen you want highest value = rank 1. - Calling
rank()on a whole DataFrame when you actually need ranks within groups — you must usegroupby().rank(). - Assuming
sort_values()changes the original df; it returns a new copy unless you useinplace=True(not recommended). - Ignoring the
na_positionparameter and getting weird sorting when NaNs appear at the top or bottom unexpectedly.
Variations
- Use
sort_index()to sort by the row index instead of a column value, which is handy after concatenating data. - Use
nlargest()/nsmallest()to grab top N rows efficiently without sorting the entire DataFrame — a faster alternative for large datasets. - When ranking ties, control the result with
method='min',method='max', ormethod='first'to match your business logic exactly.
Real-world use cases
- E-commerce dashboard: sort products by revenue to display top sellers this month.
- Sports analytics: rank athletes by a performance metric like sprint time, assign positions for the podium.
- Customer segmentation: rank customers by purchase frequency to identify VIP tiers for a loyalty program.
Key takeaways
sort_values()reorders rows;rank()adds a rank column without changing row order.- Use
ascending=Falsefor highest-first sorting andrank(ascending=False)for best = 1. - Sort by multiple columns with a list and per-column direction with
ascending=[True, False]. - Rank within groups using
df.groupby('group_col')['value'].rank(). - Handle missing values: use
na_positionfor sorting and be aware that NaN ranks become NaN. - Always assign the result of
sort_values()to a new variable or overwrite the original to keep the sorted data.
Keep learning
Related tutorials, quizzes, and articles for this topic.
Discussion
Questions, corrections, and tips help everyone reading this page.
0 comments
Add a comment
No comments yet — start the thread.