Sort and rank DataFrame values
Sort and rank DataFrame values — Python for data science.
Focus: sort and rank dataframe values
Your DataFrame is a mess — sales numbers in no order, customers scattered across names, rankings that don't exist. When you need the top 10 products or the fastest-growing segment, you want answers now, not after a hour of manual sorting. This is the exact pain this lesson solves: by the end, you'll be able to sort and rank your DataFrame values with confidence, turning chaos into insight.
The problem this lesson solves
You've loaded your data, cleaned the missing values, and grouped by category — but the results are in whatever order pandas happened to produce. That's rarely the order that matters. You need to answer questions like:
- Which 5 products generated the most revenue?
- Which customer had the longest delay?
- How does each salesperson compare to the rest of the team?
Without sorting and ranking, you're left staring at unsorted rows, manually eyeballing maximums, or writing complex loops. Sorting reorders rows by one or more columns; ranking assigns a numeric position to each row within a group or the whole frame. Together they turn raw data into a story.
Core concept / mental model
Think of your DataFrame as a deck of cards. Sorting is like arranging the deck by suit or value — you decide the order. Ranking is like dealing a card and saying "this card is the 3rd highest in the deck" — a relative position, not a reordering.
Key terms:
- sort_values(): Reorders rows based on column values. It's the workhorse for ordering.
- sort_index(): Sorts by row or column labels (the index). Useful when you have dates or custom indices.
- rank(): Assigns ranks (1, 2, 3, ...) to values, optionally within groups, with methods for handling ties.
A mental picture:
- Sorting = physical reordering → the rows move.
- Ranking = annotating → each row gets a rank number without changing row order.
You often combine them: first rank to get a new column, then sort by that rank to see the top performers at the top.
How it works step by step
Step 1 — Sort by a single column
Call df.sort_values(by='column_name') to get a new DataFrame sorted ascending (default). To sort descending, add ascending=False. Importantly, sort_values returns a new DataFrame; it doesn't modify the original unless you pass inplace=True (which we generally avoid).
import pandas as pd
df = pd.DataFrame({
'product': ['Laptop', 'Mouse', 'Keyboard', 'Monitor'],
'price': [1200, 25, 80, 300]
})
sorted_df = df.sort_values(by='price', ascending=False)
print(sorted_df)
Output:
product price
0 Laptop 1200
3 Monitor 300
2 Keyboard 80
1 Mouse 25
Step 2 — Sort by multiple columns
Use a list in by to sort by primary and secondary columns. You can provide a matching ascending list to control direction per column. Think of it like sorting a spreadsheet by "Department" then "Salary" within each department.
# Employee data: department and salary
df2 = pd.DataFrame({
'dept': ['IT', 'HR', 'IT', 'HR', 'IT'],
'salary': [90000, 70000, 110000, 60000, 95000]
})
sorted_multi = df2.sort_values(by=['dept', 'salary'], ascending=[True, False])
print(sorted_multi)
Output:
dept salary
2 IT 110000
4 IT 95000
0 IT 90000
1 HR 70000
3 HR 60000
Step 3 — Rank values
The rank() method assigns ranks from 1 (lowest) upward. The default method for ties is 'average': tied values get the average of their positions. Other methods include 'min', 'max', and 'dense'. Use ascending=False to make higher values rank 1.
df3 = pd.DataFrame({
'student': ['Alice', 'Bob', 'Charlie', 'David'],
'score': [85, 92, 85, 78]
})
df3['rank'] = df3['score'].rank(ascending=False, method='min')
print(df3)
Output:
student score rank
0 Alice 85 2
1 Bob 92 1
2 Charlie 85 2
3 David 78 4
Here, both Alice and Charlie get rank 2 (ties get the minimum rank), and the next rank jumps to 4.
Hands-on walkthrough
Let's solve a realistic problem: ranking salespeople by revenue, then sorting to see the best performer at the top.
Dataset:
import pandas as pd
sales = pd.DataFrame({
'salesperson': ['Sam', 'Alex', 'Jordan', 'Riley', 'Taylor'],
'region': ['East', 'East', 'West', 'West', 'East'],
'revenue': [50000, 60000, 55000, 70000, 45000]
})
Step 1 — Add a revenue rank (higher revenues get rank 1):
sales['revenue_rank'] = sales['revenue'].rank(ascending=False, method='min')
print(sales)
Output:
salesperson region revenue revenue_rank
0 Sam East 50000 4
1 Alex East 60000 2
2 Jordan West 55000 3
3 Riley West 70000 1
4 Taylor East 45000 5
Step 2 — Sort by region, then by revenue descending:
sorted_sales = sales.sort_values(by=['region', 'revenue'], ascending=[True, False])
print(sorted_sales)
Output:
salesperson region revenue revenue_rank
1 Alex East 60000 2
0 Sam East 50000 4
4 Taylor East 45000 5
3 Riley West 70000 1
2 Jordan West 55000 3
Step 3 — Rank within each region (like separate leaderboards):
sales['region_rank'] = sales.groupby('region')['revenue'].rank(ascending=False, method='min')
print(sales)
Output:
salesperson region revenue revenue_rank region_rank
0 Sam East 50000 4 3
1 Alex East 60000 2 1
2 Jordan West 55000 3 2
3 Riley West 70000 1 1
4 Taylor East 45000 5 4
Now you see Alex is #1 in East, and Riley is #1 in West. This gives a complete picture for a manager.
Compare options / when to choose what
| Method | Purpose | Example use case |
|---|---|---|
sort_values() |
Reorder rows by column values | Top products by sales, chronological order |
sort_index() |
Reorder rows by index label | Arranging by date index, custom IDs |
rank() |
Assign relative position per value | Rank students, percentile positions |
rank() with groupby() |
Rank within groups | Regional leaderboards, department rankings |
When to choose:
- Need the actual order visible? Use
sort_values(). - Need a new column of rank numbers? Use
rank(). - Need both? Add rank first, then sort by that column.
- Need to preserve original row order but see ranks? Use
rank()only.
Troubleshooting & edge cases
1. Sorting doesn't change the original DataFrame
sort_values() returns a new DataFrame. If you forget to assign it, nothing changes.
Fix: Assign the result or use inplace=True (not recommended for clarity).
df = df.sort_values(by='column') # correct
# df.sort_values(by='column') # no effect
Pro tip:
inplace=Trueis aliased and can be confusing; prefer the explicit assignment pattern.
2. ascending list length mismatch
If you pass two columns to by, you must provide an ascending list of the same length or a single boolean applies to all. Mismatched lists raise an error.
Fix: Always use [True, False] style lists that match the number of sort keys.
3. Handling missing values (NaN)
- Sorting puts NaN last by default (with
na_position='last'; use'first'to move NaNs up). - Ranking with NaN? By default, NaNs do not get a rank — they become NaN in the rank column. Use
na_option='keep'(default) or'top'/'bottom'to include them.
# Move NaNs to the beginning when sorting
df.sort_values(by='price', na_position='first')
# Rank with NaNs ranked last (overall)
df['rank'] = df['price'].rank(na_option='bottom')
4. Ranking ties unexpectedly
If multiple rows share the same value, default average ranking may produce fractional ranks (e.g., 2.5). That's often undesirable in business contexts. Choose method='min' or 'dense' to avoid gaps.
5. GroupBy rank column disappears
groupby().rank() returns a Series, not a DataFrame. Assign it directly to a new column as shown above; don't try to groupby().rank() inside assign without proper handling.
What you learned & what's next
You now know how to sort and rank DataFrame values — two essential operations for data exploration and reporting. You can:
- Reorder rows with
sort_values()for clear, actionable ordering. - Assign ranks with
rank(), including tie handling and group-wise ranking. - Combine sorting and ranking to build leaderboards or prioritized lists.
These skills are foundational for your next lesson, where you'll apply ranking to filter top-N rows or to feed into aggregation pipelines. You're building the toolkit to turn raw data into insights, one sorted and ranked row at a time.
Next in this track, you'll learn how to slice and dice DataFrames even further — but for now, go sort something!
Practice recap
Create a small DataFrame of your own (e.g., monthly expenses for categories) and practice: (1) sort by amount descending, (2) add a rank column using method='dense', and (3) rank within a groupby of category. Verify your outputs match expectations. This will solidify the concepts before moving to the next lesson.
Common mistakes
- Forgetting to assign the result of sort_values() back to a variable — the original DataFrame stays unchanged.
- Providing an
ascendinglist that doesn't match the length of thebylist, causing a ValueError. - Using the default
rank()method and getting unexpected average ranks for ties, when you wanted min or dense ranking. - Assuming rank() works on a groupby result like a DataFrame — it returns a Series, so assign it correctly to a column.
Variations
- Use
sort_index()when your index carries meaning (e.g., sorted date index) instead of sorting by a column. - Use
nsmallest()ornlargest()for a quick top-N without a full sort. - Use the
method='dense'in rank() when you want ranks like 1,2,2,3 with no gaps.
Real-world use cases
- E-commerce: display top 10 best-selling products by sorting revenue descending for the homepage banner.
- HR: rank employees by performance score within each department to identify promotion candidates.
- Finance: rank stocks by daily return percentage, then sort to show the best performers in a dashboard.
Key takeaways
- sort_values() reorders rows by one or more columns and returns a new DataFrame.
- rank() adds a new column of relative positions, not reordering, with flexible tie methods.
- Use ascending=[True, False] lists to sort multiple columns with different directions.
- Groupby + rank gives per-group rankings, like region-wise leaderboards.
- NaN handling differs: sort places NaNs last by default, rank leaves them as NaN unless you specify na_option.
- Combine sorting and ranking to produce clean, ranked summaries.
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.