Difficulty: Intermediate
Sorting and ranking are essential operations for organizing data in a meaningful order. Whether you need to find the top-performing students, rank products by sales, or simply display data alphabetically, Pandas provides powerful and flexible methods to accomplish these tasks efficiently. Understanding sorting is also important for data presentation, reporting, and as a preliminary step before other operations like deduplication or rolling calculations.
The sort_values() method sorts a DataFrame by one or more columns. By default, it sorts in ascending order. You can pass ascending=False to sort in descending order, or pass a list of booleans when sorting by multiple columns to control the direction for each column independently. For example, df.sort_values(['Department', 'Salary'], ascending=[True, False]) sorts by Department alphabetically and within each department, sorts by Salary from highest to lowest. The method returns a new DataFrame by default; the original remains unchanged.
The sort_index() method sorts the DataFrame by its index labels rather than by column values. This is useful after operations like groupby or filtering that may shuffle the index order. By default it sorts in ascending order, and you can pass ascending=False for descending. If your DataFrame has a MultiIndex, sort_index() sorts by all levels by default, but you can specify a particular level to sort by.
The rank() method assigns ranks to values. By default it uses the 'average' method, meaning tied values get the average of their ranks. Other ranking methods include 'min' (all tied values get the lowest rank), 'max' (all tied values get the highest rank), 'first' (tied values are ranked by their order of appearance), and 'dense' (like 'min' but with no gaps in rank values). You can rank in ascending or descending order using the ascending parameter.
The nlargest(n, column) and nsmallest(n, column) methods are optimized shortcuts for finding the top or bottom n rows by a particular column. They are faster than sorting the entire DataFrame when you only need a few extreme values, because they use a partial sort algorithm internally. These methods are perfect for "top 10" or "bottom 5" type queries and are commonly used in data analysis reports and dashboards.
import pandas as pd
df = pd.DataFrame({
'Name': ['Charlie', 'Alice', 'Eve', 'Bob', 'Diana'],
'Score': [85, 92, 78, 95, 88]
})
# Sort by Score ascending
print("Ascending:")
print(df.sort_values('Score'))
# Sort by Score descending
print("---")
print("Descending:")
print(df.sort_values('Score', ascending=False))
sort_values('Score') sorts by the Score column. The original index labels are preserved, which is why the index appears out of order. Use .reset_index(drop=True) if you want a clean 0-based index after sorting.
import pandas as pd
df = pd.DataFrame({
'Department': ['IT', 'HR', 'IT', 'HR', 'IT'],
'Name': ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve'],
'Salary': [70000, 50000, 60000, 55000, 65000]
})
# Sort by Department (asc), then Salary (desc)
print(df.sort_values(['Department', 'Salary'], ascending=[True, False]))
When sorting by multiple columns, pass a list of column names and a corresponding list of ascending booleans. HR comes before IT alphabetically, and within each department, salaries are sorted from highest to lowest.
import pandas as pd
df = pd.DataFrame({
'City': ['Delhi', 'Mumbai', 'Pune', 'Chennai', 'Kolkata'],
'Population': [20000000, 18000000, 7000000, 10000000, 15000000]
})
print("Top 3 by population:")
print(df.nlargest(3, 'Population'))
print("---")
print("Bottom 2 by population:")
print(df.nsmallest(2, 'Population'))
nlargest(3, 'Population') returns the 3 rows with the highest population. nsmallest(2, 'Population') returns the 2 rows with the lowest. These are more efficient than sorting the entire DataFrame when you only need a few results.
import pandas as pd
df = pd.DataFrame({
'Student': ['Alice', 'Bob', 'Charlie', 'Diana'],
'Score': [88, 95, 88, 72]
})
df['Rank_avg'] = df['Score'].rank(ascending=False, method='average')
df['Rank_min'] = df['Score'].rank(ascending=False, method='min')
df['Rank_dense'] = df['Score'].rank(ascending=False, method='dense')
print(df)
With ascending=False, the highest score gets rank 1. Alice and Charlie are tied at 88. With 'average', they both get 2.5 (average of ranks 2 and 3). With 'min', they both get 2. With 'dense', they get 2 and the next rank is 3 (no gap).
sort_values(), sort_index(), rank(), nlargest(), nsmallest()