HOWTO · Pandas
How to Set Columns as Index in Pandas Dataframe
This tutorial demonstrates how to set columns as the index in a Pandas DataFrame using the set_index() method and the index_col parameter when reading a file. Learn efficient techniques to organize your data and streamline your analysis in Python with step-by-step examples and clear explanations. Enhance your data manipulation skills and improve your workflow today.
On this page
A new Pandas DataFrame uses a default integer index to identify its rows. To use meaningful row labels, call set_index() on an existing DataFrame, or pass index_col to read_csv or read_excel as the file is loaded. The first approach is useful when the data is already in memory; the second chooses labels during file import. The examples below use the same small people dataset so you can compare the results. Choose a column whose values make rows easy to identify in your analysis; an index can contain repeated values, though a lookup by a repeated label can return more than one row.
Set a DataFrame column as its index with set_index()
set_index() is a DataFrame method. By default, it returns a new DataFrame and removes the selected column from the regular columns. Assign the result when you want to keep the original DataFrame unchanged. Pass a list of column names to create a MultiIndex, which identifies each row using a combination of values. Use drop=False when the selected values should also remain available as regular data columns.
These choices affect how you access the data, not whether its rows are discarded. For example, keep a name column when later code needs it as both a label and a value, or use a city-and-age MultiIndex when that pair is meaningful for your work. If you want to change the existing DataFrame itself, set_index(..., inplace=True) performs that mutation and returns None; assigning the default returned DataFrame is usually easier to follow and lets you preserve the original. To go back to a regular index, reset_index() places the current index values in columns and gives the result a new integer index by default. This is useful before exporting data or when later operations expect the labels to be ordinary columns.
The following example builds the people DataFrame, then creates indexes from one column and from two columns. It also shows how to retain the name column while using it for row labels.
import pandas as pd
people = pd.DataFrame({
"Name": ["Alice", "Bob", "Charlie"],
"City": ["New York", "Los Angeles", "Chicago"],
"Age": [25, 30, 35],
})
by_name = people.set_index("Name")
by_city_and_age = people.set_index(["City", "Age"])
with_name_column = people.set_index("Name", drop=False)
print(by_name)
Here, by_name has names as its row labels and keeps City and Age as data columns. by_city_and_age uses both selected columns as a MultiIndex, while with_name_column uses names as labels and also retains the Name column. The assignments create separate DataFrames, so people remains available with its original columns and default index. The print statement displays the single-column result; the same inspection works for the other two variables. To restore a regular integer index and put index values back into columns, call by_name.reset_index(); this returns another DataFrame. You can assign that result if you want to continue working with the reset version.
Set the index while reading a CSV or Excel file with index_col
When the source is a file, select the index as the data is read. This self-contained CSV example uses the same column names and records as the DataFrame above. StringIO lets read_csv consume the sample text directly, so you can adapt the call by replacing it with a file path such as "people.csv" when you have a CSV on disk:
from io import StringIO
import pandas as pd
csv_data = StringIO("""Name,City,Age
Alice,New York,25
Bob,Los Angeles,30
Charlie,Chicago,35
""")
people = pd.read_csv(csv_data, index_col="Name")
print(people)
The index_col="Name" argument selects the column by its header, so the resulting index and remaining data columns match by_name in the first example. A numeric index_col instead selects a column by its zero-based position, with the first column at position 0; using a header name makes the choice explicit and less dependent on column order. With multiple selected columns, pass a list such as index_col=["City", "Age"] to build a MultiIndex during import. For an Excel workbook, use the corresponding reader call pd.read_excel("people.xlsx", index_col="Name"). The workbook must be available, and pandas needs an appropriate Excel engine installed to read its format. The Excel call is shown as a pattern because no workbook is supplied here. If a header is misspelled or the file’s column order changes, confirm the file’s column names before choosing the index so the intended field is selected.