If your row labels no longer line up with the table—common after a groupby, a filter, or a sort—reset_index() is how you put the index back in order. By default it turns the current index into a normal column and gives you a fresh 0, 1, 2, … down the side; with drop=True it skips that extra column and only keeps the new numbering. The examples below use both DataFrame and Series.
Tested environment: Every
pythonblock below was run and tested withpython3on Ubuntu (Python 3.13.3, pandas 2.2.3).
Quick reference
| What you want | Typical pattern |
|---|---|
| Default pandas reset index (keep old index as a column) | df.reset_index() |
| Reset index to start at 0 without an extra index column | df.reset_index(drop=True) |
| Pandas groupby reset index | df.groupby('col').sum().reset_index() |
| Same idea without MultiIndex first | df.groupby('col', as_index=False).sum() |
| df reset_index (same API) | df.reset_index(...) |
| Reset column index (rename columns to 0, 1, …) | df.columns = range(len(df.columns)) |
After reshaping data, you can print the entire DataFrame to confirm row labels and columns.
Default reset_index() on a DataFrame
By default, reset_index() moves the row index into a new column and assigns a new integer index from 0 upward—useful when strings, dates, or ids on the index should become ordinary columns again.
import pandas as pd
df = pd.DataFrame({"A": [1, 2, 3]}, index=["x", "y", "z"])
print(df)
print("---")
df_reset = df.reset_index()
print(df_reset) A
x 1
y 2
z 3
---
index A
0 x 1
1 y 2
2 z 3The new column is named index unless your index had a name.
drop=True: reset index to start at 0 without an extra column
For pandas reset index to start at 0 and no added column, pass drop=True. Use this when the old labels are not useful anymore (for example after sorting or subsetting).
import pandas as pd
df = pd.DataFrame({"A": [1, 2]}, index=["x", "y"])
print(df.reset_index(drop=True)) A
0 1
1 2Pandas groupby reset index
After groupby, group keys often sit on the index. Calling reset_index() turns them back into regular columns — the usual pandas groupby reset index pattern. For a deeper tour of grouping, see the pandas groupby guide on this site.
import pandas as pd
df = pd.DataFrame(
{
"A": [1, 2, 3, 1, 2, 3],
"B": [4, 5, 6, 4, 5, 6],
"C": [7, 8, 9, 7, 8, 9],
}
)
grouped_df = df.groupby("A").sum().reset_index()
print(grouped_df) A B C
0 1 8 14
1 2 10 16
2 3 12 18Alternative (no reset_index call): df.groupby("A", as_index=False).sum() produces the same aggregated values for this data; choose it when you never need the grouped object as a MultiIndex and want to skip an extra step.
MultiIndex rows
If the row index has multiple levels, reset_index() flattens each level into its own column unless you pass level.
import pandas as pd
arrays = [["a", "a", "b", "b"], [0, 1, 0, 1]]
idx = pd.MultiIndex.from_arrays(arrays, names=["letter", "num"])
df = pd.DataFrame({"value": [10, 20, 30, 40]}, index=idx)
print(df.reset_index()) letter num value
0 a 0 10
1 a 1 20
2 b 0 30
3 b 1 40Rename the new column after reset_index()
If you keep the old index as a column, you may want a clearer name than index.
import pandas as pd
df = pd.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6], "C": [7, 8, 9]}, index=["a", "b", "c"])
df = df.reset_index().rename(columns={"index": "original_index"})
print(df) original_index A B C
0 a 1 4 7
1 b 2 5 8
2 c 3 6 9Start row labels at 1 instead of 0
The default index after reset_index() starts at 0. To start at 1, reset first then shift the RangeIndex (avoid off-by-one on empty frames in real pipelines).
import pandas as pd
df = pd.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6], "C": [7, 8, 9]}, index=["a", "b", "c"])
df = df.reset_index()
df.index = df.index + 1
print(df) index A B C
1 a 1 4 7
2 b 2 5 8
3 c 3 6 9Series reset_index()
Series.reset_index() returns a DataFrame with two columns: the old index (name index by default) and the series values (often column 0 until you rename).
import pandas as pd
s = pd.Series([1, 2, 3], index=["a", "b", "c"])
print(s)
print("---")
print(s.reset_index())a 1
b 2
c 3
dtype: int64
---
index 0
0 a 1
1 b 2
2 c 3After sort_values()
Sorting keeps the original index attached to each row. Reset index in pandas after sort when you want row numbers to follow the new row order.
import pandas as pd
df = pd.DataFrame({"A": [3, 2, 1], "B": [6, 5, 4], "C": [9, 8, 7]}, index=["c", "b", "a"])
sorted_df = df.sort_values("A").reset_index()
print(sorted_df) index A B C
0 a 1 4 7
1 b 2 5 8
2 c 3 6 9After query() or boolean filtering
Filtered rows keep old index labels, so you see gaps in the index sequence. reset_index() fixes reset index in pandas after subsetting.
import pandas as pd
df = pd.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6], "C": [7, 8, 9]}, index=["a", "b", "c"])
filtered_df = df.query("A > 1").reset_index()
print(filtered_df) index A B C
0 b 2 5 8
1 c 3 6 9Pandas reset column index (column labels 0, 1, …)
Row reset_index() does not rename columns. For pandas reset column index, assign integer column labels after you are done shaping the frame:
import pandas as pd
df = pd.DataFrame([[10, 20], [30, 40]], columns=["foo", "bar"])
print("before:")
print(df)
df.columns = range(df.shape[1])
print("after:")
print(df)before:
foo bar
0 10 20
1 30 40
after:
0 1
0 10 20
1 30 40Syntax and parameters (reference)
From the official API, the signature is essentially:
DataFrame.reset_index(level=None, drop=False, inplace=False, col_level=0, col_fill='', ...)level— reset only some levels of a MultiIndex.drop— if True, discard the old index instead of adding a column.inplace— if True, mutatedfand return None.col_level/col_fill— placement when columns are MultiIndex.
Newer pandas versions add extra keyword arguments; see pandas.DataFrame.reset_index for your exact version.
To put one or more columns onto the index instead, use set_index — see pandas set index on this site.
Summary
Reset index pandas workflows boil down to: use reset_index() when the index should become data again, reset_index(drop=True) when you only want a clean 0..n-1 dataframe reset index, and groupby(...).sum().reset_index() (or as_index=False) for groupby reset index results. For column labels, assign df.columns. All examples above were verified on pandas 2.2.3 so you can trust the printed output.
Frequently Asked Questions
How do I reset index in pandas?
Call DataFrame.reset_index() or Series.reset_index(). By default the old row index becomes a new column and rows are numbered 0, 1, 2. Use drop=True if you do not want to keep the old index as a column.
How do I do a pandas groupby reset index?
After aggregation, chain reset_index, for example df.groupby('A').sum().reset_index(). Alternatively pass as_index=False to groupby so keys stay as columns without an extra reset step.
How do I reset index in pandas to start at 0?
After reset_index the default row index is already 0-based. If you only want consecutive labels and no old-index column, use reset_index(drop=True). If the index is already 0-based but non-consecutive after filtering, reset_index or reset_index(drop=True) fixes the row labels.
What does df reset_index do?
df.reset_index is the same as DataFrame.reset_index. It returns a new frame unless inplace=True, with the previous index stored as a column when drop=False.
How do I reset the column index in pandas?
Row index and column labels are different. To replace column names with default integers use df.columns = range(len(df.columns)) after your edits.
What is the difference between reset_index and set_index?
set_index moves columns into the row index. reset_index moves the row index into columns or drops it with drop=True. See also set_index tutorials on this site for the opposite operation.
Should I use inplace=True with reset_index?
inplace=True mutates the DataFrame in place and returns None. Most teams prefer df = df.reset_index() for clearer, chainable code.
Can reset_index handle a MultiIndex?
Yes. Calling reset_index on a MultiIndex DataFrame turns each index level into its own column unless you pass level to reset only part of the hierarchy.
Why does my DataFrame index look wrong after filter or sort?
Filtering with a boolean mask or sorting with sort_values keeps the original index labels on the remaining rows, so labels can skip numbers. Reset the index to get a clean 0..n-1 row label sequence.
Is reset_index the same as reindex?
No. reset_index changes which values are used as the index and moves the old index into columns. reindex aligns rows to a new index label set and can introduce missing values.
References
- pandas.DataFrame.reset_index (official)

