Skip to content
Laviyx Learn

Try

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.

Beginner8 min readUpdated
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#

Python
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))
Output
    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    40

sort_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:

Python
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))
Output
    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    40

reset_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":

Python
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])
Output
    product  price  sold
1     Mouse    700   300
3  Keyboard   1500   120
Mouse

Sorting by the index#

Python
import pandas as pd

stock = pd.Series({"pens": 120, "books": 15, "erasers": 60})
print(stock.sort_index())
print(stock.sort_values(ascending=False))
Output
books       15
erasers     60
pens       120
dtype: int64
pens       120
erasers     60
books       15
dtype: int64

Ranking#

rank gives each value its position, which is useful for leaderboards and percentiles. The method argument decides how ties are numbered:

Python
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)
Output
  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      2
  • average (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
Python
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"]])
Output
    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    85

Key takeaway#

Next: Adding and Changing Columns.

Finished this lesson?