Skip to content

Python Pandas: How to Reorder DataFrame Rows Based on a List of Index Labels

Learn how to rearrange Pandas DataFrame rows using reindex() or loc[] with a custom list of index labels for specific ordering needs.

Rearranging the order of rows in a Pandas DataFrame according to a custom sequence of its index labels is a common data manipulation task. You might need to present data in a specific order, align it with another dataset, or simply organize it for better readability.

This guide explains how to reorder DataFrame rows based on a provided list of index labels, primarily using DataFrame.reindex() and DataFrame.loc[].

The Goal: Custom Row Ordering by Index Labels

Given a Pandas DataFrame with an existing index (which could be strings, numbers, datetimes, etc.), and a separate Python list containing some or all of those index labels in a new desired order, we want to create a new DataFrame where the rows are arranged according to this new order.

Example DataFrame with a Custom Index

We'll use a DataFrame with string labels for its index.

import pandas as pd

data = {
    'Product Name': ['Laptop', 'Mouse', 'Keyboard', 'Monitor', 'Webcam'],
    'Category': ['Electronics', 'Accessories', 'Accessories', 'Electronics', 'Accessories'],
    'Price': [1200, 25, 75, 300, 45],
    'Stock': [10, 150, 75, 20, 90]
}
index_labels = ['P101', 'A205', 'A210', 'P107', 'A215']
df_original = pd.DataFrame(data, index=index_labels)

print("Original DataFrame:")
print(df_original)

Output:

Original DataFrame:
     Product Name     Category  Price  Stock
P101       Laptop  Electronics   1200     10
A205        Mouse  Accessories     25    150
A210     Keyboard  Accessories     75     75
P107      Monitor  Electronics    300     20
A215       Webcam  Accessories     45     90

The DataFrame.reindex() method is specifically designed to conform a DataFrame to a new index. When you pass a list of labels to its labels parameter (or just as the first positional argument if only reindexing rows), it will reorder the existing rows according to that list.

import pandas as pd

df = pd.DataFrame({
    'Product Name': ['Laptop', 'Mouse', 'Keyboard', 'Monitor', 'Webcam'],
    'Category': ['Electronics', 'Accessories', 'Accessories', 'Electronics', 'Accessories'],
    'Price': [1200, 25, 75, 300, 45],
    'Stock': [10, 150, 75, 20, 90]
}, index=['P101', 'A205', 'A210', 'P107', 'A215'])


custom_index_order = ['A210', 'P107', 'P101', 'A215', 'A205']

df_reordered_reindex = df.reindex(labels=custom_index_order)

print("DataFrame reordered using df.reindex():")
print(df_reordered_reindex)

Output:

DataFrame reordered using df.reindex():
     Product Name     Category  Price  Stock
A210     Keyboard  Accessories     75     75
P107      Monitor  Electronics    300     20
P101       Laptop  Electronics   1200     10
A215       Webcam  Accessories     45     90
A205        Mouse  Accessories     25    150
  • df.reindex(labels=custom_index_order): Creates a new DataFrame with rows arranged in the order specified by custom_index_order.
  • If custom_index_order contains labels not present in the original DataFrame's index, reindex will introduce rows with NaN values for those labels by default (this behavior can be controlled with the fill_value parameter).
  • If custom_index_order omits labels present in the original index, those rows will be dropped from the result.

Method 2: Using DataFrame.loc[index_list]

The DataFrame.loc[] indexer, which is primarily for label-based selection, can also accept a list of index labels. It will return a new DataFrame with rows selected in the order they appear in the provided list.

import pandas as pd

df = pd.DataFrame({
    'Product Name': ['Laptop', 'Mouse', 'Keyboard', 'Monitor', 'Webcam'],
    'Category': ['Electronics', 'Accessories', 'Accessories', 'Electronics', 'Accessories'],
    'Price': [1200, 25, 75, 300, 45],
    'Stock': [10, 150, 75, 20, 90]
}, index=['P101', 'A205', 'A210', 'P107', 'A215'])

custom_index_order = ['A210', 'P107', 'P101', 'A215', 'A205']

df_reordered_loc = df.loc[custom_index_order]

print("DataFrame reordered using df.loc[]:")
print(df_reordered_loc)

Output:

DataFrame reordered using df.loc[]:
     Product Name     Category  Price  Stock
A210     Keyboard  Accessories     75     75
P107      Monitor  Electronics    300     20
P101       Laptop  Electronics   1200     10
A215       Webcam  Accessories     45     90
A205        Mouse  Accessories     25    150
  • df.loc[custom_index_order]: Selects rows based on the labels in custom_index_order and arranges them in that sequence.
  • Important Difference from reindex: If custom_index_order contains labels not present in df.index, df.loc[] will raise a KeyError. reindex is more flexible in handling missing/new labels. If your list of labels is guaranteed to be a permutation or subset of existing index labels, .loc[] is a concise alternative.

Important Consideration: Handling Missing/Extra Labels in index_list

  • df.reindex(new_labels):
    • If new_labels contains labels not in the original index, new rows filled with NaN (or fill_value if specified) are added.
    • If new_labels omits labels from the original index, those rows are dropped.
  • df.loc[new_labels]:
    • If new_labels contains labels not in the original index, a KeyError is raised.
    • If new_labels omits labels, only the specified rows are selected (effectively dropping the others).

Choose reindex if you need to conform to a new index that might have different labels. Choose loc if you are sure your new_labels list contains only existing index labels and you want to select/reorder them.

Alternative: Sorting by Index (sort_index())

If your goal is not a custom arbitrary order but rather to sort the rows based on their index labels (alphabetically, numerically, etc.), use DataFrame.sort_index().

import pandas as pd

df_original = pd.DataFrame({
    'Product Name': ['Laptop', 'Mouse', 'Keyboard', 'Monitor', 'Webcam'],
    'Category': ['Electronics', 'Accessories', 'Accessories', 'Electronics', 'Accessories'],
    'Price': [1200, 25, 75, 300, 45],
    'Stock': [10, 150, 75, 20, 90]
}, index=['P101', 'A205', 'A210', 'P107', 'A215'])

df_shuffled = df_original.sample(frac=1, random_state=42) # Shuffle for demo
print("Shuffled DataFrame before sort_index():")
print(df_shuffled)
print()

df_sorted_asc = df_shuffled.sort_index(ascending=True)
print("DataFrame sorted by index (ascending):")
print(df_sorted_asc)
print()

df_sorted_desc = df_shuffled.sort_index(ascending=False)
print("DataFrame sorted by index (descending):")
print(df_sorted_desc)

Output:

Shuffled DataFrame before sort_index():
     Product Name     Category  Price  Stock
A205        Mouse  Accessories     25    150
A215       Webcam  Accessories     45     90
A210     Keyboard  Accessories     75     75
P101       Laptop  Electronics   1200     10
P107      Monitor  Electronics    300     20

DataFrame sorted by index (ascending):
     Product Name     Category  Price  Stock
A205        Mouse  Accessories     25    150
A210     Keyboard  Accessories     75     75
A215       Webcam  Accessories     45     90
P101       Laptop  Electronics   1200     10
P107      Monitor  Electronics    300     20

DataFrame sorted by index (descending):
     Product Name     Category  Price  Stock
P107      Monitor  Electronics    300     20
P101       Laptop  Electronics   1200     10
A215       Webcam  Accessories     45     90
A210     Keyboard  Accessories     75     75
A205        Mouse  Accessories     25    150

Conclusion

To reorder Pandas DataFrame rows based on a specific list of its existing index labels:

  • df.reindex(labels=your_custom_list_of_labels): This is the most flexible method, as it can handle cases where the custom list might include new labels (filling with NaN) or omit existing ones (dropping them). Generally recommended.
  • df.loc[your_custom_list_of_labels]: This is a concise alternative if you are certain that your_custom_list_of_labels only contains labels already present in the DataFrame's index and you simply want to select and reorder those specific rows. It will raise a KeyError if any label in the list is not found in the index.

If your goal is simply to sort the DataFrame by its index labels in ascending or descending order, use df.sort_index(). Choose the method that best suits your specific reordering needs and how you want to handle discrepancies between your custom list and the DataFrame's current index.

Navigation