Python for Data course menu
Sorting and Ranking in pandas: sort_values, nlargest and rank
Sort pandas DataFrames by one or more columns, in ascending or descending order, sort by the index, get top rows quickly with nlargest and nsmallest, and rank values with different tie methods.
On this page
Sorting answers "who are the top customers?" and "which products sell least?". pandas sorts by any column, by several columns, or by the index, and can rank values directly.
sort_values#
import pandas as pd
products = pd.DataFrame({
"product": ["Laptop", "Mouse", "Monitor", "Keyboard", "Webcam"],
"category": ["Computers", "Accessories", "Computers", "Accessories", "Accessories"],
"price": [55000, 700, 12000, 1500, 2500],
"sold": [40, 300, 85, 120, 85],
})
print(products.sort_values("price"))
print(products.sort_values("sold", ascending=False)) product category price sold
1 Mouse Accessories 700 300
3 Keyboard Accessories 1500 120
4 Webcam Accessories 2500 85
2 Monitor Computers 12000 85
0 Laptop Computers 55000 40
product category price sold
1 Mouse Accessories 700 300
3 Keyboard Accessories 1500 120
2 Monitor Computers 12000 85
4 Webcam Accessories 2500 85
0 Laptop Computers 55000 40sort_values returns a new, sorted DataFrame; the original is unchanged. The row labels move with their rows.
Several columns#
Pass lists to sort by one column and break ties with another, each with its own direction:
import pandas as pd
products = pd.DataFrame({
"product": ["Laptop", "Mouse", "Monitor", "Keyboard", "Webcam"],
"category": ["Computers", "Accessories", "Computers", "Accessories", "Accessories"],
"price": [55000, 700, 12000, 1500, 2500],
"sold": [40, 300, 85, 120, 85],
})
print(products.sort_values(["category", "price"], ascending=[True, False]))
print(products.sort_values(["sold", "product"], ascending=[False, True]).reset_index(drop=True)) product category price sold
4 Webcam Accessories 2500 85
3 Keyboard Accessories 1500 120
1 Mouse Accessories 700 300
0 Laptop Computers 55000 40
2 Monitor Computers 12000 85
product category price sold
0 Mouse Accessories 700 300
1 Keyboard Accessories 1500 120
2 Monitor Computers 12000 85
3 Webcam Accessories 2500 85
4 Laptop Computers 55000 40reset_index(drop=True) renumbers the rows 0, 1, 2, … after sorting, throwing the old labels away.
Top and bottom rows#
nlargest and nsmallest are shortcuts for "sort and take the first n":
import pandas as pd
products = pd.DataFrame({
"product": ["Laptop", "Mouse", "Monitor", "Keyboard", "Webcam"],
"price": [55000, 700, 12000, 1500, 2500],
"sold": [40, 300, 85, 120, 85],
})
print(products.nlargest(2, "sold"))
print(products.nsmallest(1, "price")["product"].iloc[0]) product price sold
1 Mouse 700 300
3 Keyboard 1500 120
MouseSorting by the index#
import pandas as pd
stock = pd.Series({"pens": 120, "books": 15, "erasers": 60})
print(stock.sort_index())
print(stock.sort_values(ascending=False))books 15
erasers 60
pens 120
dtype: int64
pens 120
erasers 60
books 15
dtype: int64Ranking#
rank gives each value its position, which is useful for leaderboards and percentiles. The method argument decides how ties are numbered:
import pandas as pd
scores = pd.DataFrame({
"student": ["Asha", "Ravi", "Meera", "John", "Priya"],
"score": [92, 85, 92, 78, 85],
})
scores["average"] = scores["score"].rank(ascending=False)
scores["min"] = scores["score"].rank(ascending=False, method="min")
scores["dense"] = scores["score"].rank(ascending=False, method="dense").astype(int)
print(scores) student score average min dense
0 Asha 92 1.5 1.0 1
1 Ravi 85 3.5 3.0 2
2 Meera 92 1.5 1.0 1
3 John 78 5.0 5.0 3
4 Priya 85 3.5 3.0 2average(the default): tied values share the mean of their positions (1.5).min: ties share the best position, and the next rank skips ahead, like sports rankings.dense: ties share a rank and the next rank does not skip.
These match SQL's RANK and DENSE_RANK.
Common mistakes#
Practice#
Practice exercise
Using the products DataFrame (with category), add a revenue column (price × sold), then print the products sorted by revenue from highest to lowest with a clean 0-based index, and the best-selling product in each category (by sold).
Show hint
For the best per category, sort by sold descending and keep the first row of each category with drop_duplicates("category").
Show solution
import pandas as pd
products = pd.DataFrame({
"product": ["Laptop", "Mouse", "Monitor", "Keyboard", "Webcam"],
"category": ["Computers", "Accessories", "Computers", "Accessories", "Accessories"],
"price": [55000, 700, 12000, 1500, 2500],
"sold": [40, 300, 85, 120, 85],
})
products["revenue"] = products["price"] * products["sold"]
print(products.sort_values("revenue", ascending=False).reset_index(drop=True))
print(products.sort_values("sold", ascending=False).drop_duplicates("category")[["category", "product", "sold"]]) product category price sold revenue
0 Laptop Computers 55000 40 2200000
1 Monitor Computers 12000 85 1020000
2 Webcam Accessories 2500 85 212500
3 Mouse Accessories 700 300 210000
4 Keyboard Accessories 1500 120 180000
category product sold
1 Accessories Mouse 300
2 Computers Monitor 85Key takeaway#
Next: Adding and Changing Columns.
Finished this lesson?