关于Pandas版本: 本文基于 pandas2.2.0 编写。
关于本文内容更新: 随着pandas的stable版本更迭,本文持续更新,不断完善补充。
传送门: Pandas API参考目录
传送门: Pandas 版本更新及新特性
传送门: Pandas 由浅入深系列教程
本节目录
Pandas.DataFrame.reset_index()
pandas.DataFrame.reset_index
方法用于将 DataFrame
的索引,重置为数字索引。如果 DataFrame
具有 MultiIndex
(多层索引),则此方法可以重置一个或多个级别。
默认状态下,reset_index()
会把原索引插入到 DataFrame
作为普通的数据列。例
语法:
DataFrame.reset_index(level=None, * , drop=False, inplace=False, col_level=0, col_fill=‘’, allow_duplicates=_NoDefault.no_default, names=None)
返回值:
-
DataFrame or None
如果
inplace
设置为True
则返回None
否则返回一个新的DataFrame
。
参数说明:
level 指定要重置的索引级别
-
level : int, str, tuple, or list, default None 例
指定要重置的索引级别,默认为
None
表示重置所有级别的索引,level
参数接受以下类型的传入:- int: 索引的层级编号(从0开始);
- str: 索引的
name
(索引名) ; - tuple or list: 如果只想重置多个索引层级中的几个,可以传入元组或列表。列表或元组可以由层级编号构成,也可以由索引的
name
(索引名)构成,支持混用。
drop 是否舍弃原索引
-
drop : bool, default False
drop
参数用于控制是否舍弃原索引,默认为False
,原索引会插入到DataFrame
里作为普通的数据列。如果
drop=True
则原索引会被舍弃。例
inplace 原地生效
-
inplace : bool, default False
inplace
参数控制着是否让修改在原DataFrame
内生效:- 默认为
False
,表示返回一个新的DataFrame
,而不修改原始的DataFrame
。 - 如果设置为
True
,则在原始DataFrame
上进行就地修改,并返回None
。 例
- 默认为
col_level 列名插入级别
-
col_level : int or str, default 0 例
col_level
参数用于控制 原索引 的 索引名 插入到DataFrame
哪个列名层级,默认插入到最顶层(0层)。说明:当重置索引后,原索引默认会插入到
DataFrame
做基本数据使用(除非指定了drop=True
)。此时如果列名恰好具有多个级别,则默认插入到第 0 个列名层级。col_level
参数接受以下类型的传入:- int: 列名的数字层级编号;
- str: 列名的层级名称字符串。
col_fill 列命名规则
-
col_fill : object, default ‘’
col_fill
参数用于控制 原索引 的 索引名 插入到DataFrame
列名层级 时,其他列名层级 的填充方法,默认为空。说明:当重置索引后,原索引默认会插入到
DataFrame
做基本数据使用(除非指定了drop=True
)。此时如果列名恰好具有多个级别,则默认插入到第 0 个列名层级。其他层级的对应列名位,会保持为空。col_fill
参数接受以下类型的传入:- object: 字符串,用于指定原索引插入到DataFrame后,其他层级的列名(剩余的其他所有列名层级都会被这个名字填充);例
allow_duplicates 列名是否可以重复
-
allow_duplicates : bool, optional, default lib.no_default
allow_duplicates
参数用于控制列名是否允许重复:例allow_duplicates 参数接受以下类型的输入:
- True: 表示允许产生重复列名;
- False: 表示不允许产生重复列名。
✅ 新增于 Pandas 1.5.0 :
allow_duplicates
参数,新增于Pandas 1.5.0 版本。
⚠️ BUG :
- 官方文档中,关于
allow_duplicates
参数的描述是,默认lib.no_default
表示允许重置索引后,产生重复的列名,但是经实际测试,默认状态下是不允许列名重复的!例
names 索引重置后的列名重命名
-
names : int, str or 1-dimensional list, default None
索引被重置后,如果是插入到
DataFrame
作为数据列,可以使用names
参数修改其列名。默认为None
即不做修改。如果有多个索引被重置,则必须是 长度 等于 被重置的索引数量 的 列表或元组 。
names
参数接受以下类型的传入:
行索引层数 | 列名层数 | 传入类型 |
---|---|---|
1 | 1 | Int、str |
2 | 1 | 列表 |
1 | 2 | 1个列表套1个元组 |
2 | 2 | 1个列表套2个元组 |
✅ 新增于 Pandas 1.5.0 :
names
参数,新增于Pandas 1.5.0 版本。
相关方法:
➡️ 相关方法
为
DataFrame
添加索引重索引
仿制索引
示例:
测试文件下载:
本文所涉及的测试文件,如有需要,可在文章顶部的绑定资源处下载。
若发现文件无法下载,应该是资源包有内容更新,正在审核,请稍后再试。或站内私信作者索要。
示例:默认状态下,会把重置的索引插入到 DataFrame
作为普通的数据列
- 1、创建演示数据观察原始df
import pandas as pd
# 创建示例 DataFrame,带有多级索引
data = {'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9]}
index = pd.MultiIndex.from_tuples([('X', 'a'), ('Y', 'b'), ('Z', 'c')], names=['Index1', 'Index2'])
df = pd.DataFrame(data, index=index)
# 观察原始df
df
A | B | C | ||
---|---|---|---|---|
Index1 | Index2 | |||
X | a | 1 | 4 | 7 |
Y | b | 2 | 5 | 8 |
Z | c | 3 | 6 | 9 |
- 2、重置索引后,Index1和Index2会被插入到DataFrame
df.reset_index(inplace=True)
# 观察重置索引后的df
df
Index1 | Index2 | A | B | C | |
---|---|---|---|---|---|
0 | X | a | 1 | 4 | 7 |
1 | Y | b | 2 | 5 | 8 |
2 | Z | c | 3 | 6 | 9 |
- 1、构建演示数据并查看
import pandas as pd
# 创建示例 DataFrame,带有多级索引
data = {'A': [1, 2, 3, 33], 'B': [4, 5, 6, 66], 'C': [7, 8, 9, 99]}
index = pd.MultiIndex.from_tuples([('W', 'a'), ('X', 'b'), ('Y', 'c'), ('Z', 'd')], names=['Index1', 'Index2'])
df = pd.DataFrame(data, index=index)
# 查看原始数据
df
A | B | C | ||
---|---|---|---|---|
Index1 | Index2 | |||
W | a | 1 | 4 | 7 |
X | b | 2 | 5 | 8 |
Y | c | 3 | 6 | 9 |
Z | d | 33 | 66 | 99 |
- 2、使用索引名重置index2
df2 = df.reset_index(level='Index2')
df2
Index2 | A | B | C | |
---|---|---|---|---|
Index1 | ||||
W | a | 1 | 4 | 7 |
X | b | 2 | 5 | 8 |
Y | c | 3 | 6 | 9 |
Z | d | 33 | 66 | 99 |
- 3、使用层级编号重置index2
df3 = df.reset_index(level=1)
df3
Index2 | A | B | C | |
---|---|---|---|---|
Index1 | ||||
W | a | 1 | 4 | 7 |
X | b | 2 | 5 | 8 |
Y | c | 3 | 6 | 9 |
Z | d | 33 | 66 | 99 |
- 4、使用元组,同时重置index1和index2
df4 = df.reset_index(level=(0,1))
df4
Index1 | Index2 | A | B | C | |
---|---|---|---|---|---|
0 | W | a | 1 | 4 | 7 |
1 | X | b | 2 | 5 | 8 |
2 | Y | c | 3 | 6 | 9 |
3 | Z | d | 33 | 66 | 99 |
- 5、使用列表,同时重置index1和index2
df5 = df.reset_index(level=['Index1','Index2'])
df5
Index1 | Index2 | A | B | C | |
---|---|---|---|---|---|
0 | W | a | 1 | 4 | 7 |
1 | X | b | 2 | 5 | 8 |
2 | Y | c | 3 | 6 | 9 |
3 | Z | d | 33 | 66 | 99 |
- 6、层级编号、索引名支持混用
df6 = df.reset_index(level=(0,'Index2'))
df6
Index1 | Index2 | A | B | C | |
---|---|---|---|---|---|
0 | W | a | 1 | 4 | 7 |
1 | X | b | 2 | 5 | 8 |
2 | Y | c | 3 | 6 | 9 |
3 | Z | d | 33 | 66 | 99 |
示例:drop=True
被重置的原索引会被舍弃,不会被插入到DataFrame
import pandas as pd
# 创建示例 DataFrame,带有多级索引
data = {'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9]}
index = pd.MultiIndex.from_tuples([('X', 'a'), ('Y', 'b'), ('Z', 'c')], names=['Index1', 'Index2'])
df = pd.DataFrame(data, index=index)
# 重置索引,并舍弃原索引
df7 = df.reset_index(drop=True)
df7
A | B | C | |
---|---|---|---|
0 | 1 | 4 | 7 |
1 | 2 | 5 | 8 |
2 | 3 | 6 | 9 |
import pandas as pd
# 创建示例 DataFrame,带有多级索引
data = {'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9]}
index = pd.MultiIndex.from_tuples([('X', 'a'), ('Y', 'b'), ('Z', 'c')], names=['Index1', 'Index2'])
df = pd.DataFrame(data, index=index)
# 重置索引,并原地生效
df.reset_index(inplace=True)
df
Index1 | Index2 | A | B | C | |
---|---|---|---|---|---|
0 | X | a | 1 | 4 | 7 |
1 | Y | b | 2 | 5 | 8 |
2 | Z | c | 3 | 6 | 9 |
import pandas as pd
# 创建示例 DataFrame,带有多级列索引
data = {'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9]}
index = pd.Index(['X', 'Y', 'Z'], name='Index')
columns = pd.MultiIndex.from_tuples([('A', 'a'), ('B', 'b'), ('C', 'c')],names=['Column1', 'Column2'])
df = pd.DataFrame(data, index=index, columns=columns)
df
Column1 | A | B | C |
---|---|---|---|
Column2 | a | b | c |
Index | |||
X | NaN | NaN | NaN |
Y | NaN | NaN | NaN |
Z | NaN | NaN | NaN |
- 1、构建具有多层列名的演示数据并观察层级名称
import pandas as pd
# 创建示例 DataFrame,带有多级列索引
data = {'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9]}
index = pd.Index(['X', 'Y', 'Z'], name='Index')
columns = pd.MultiIndex.from_tuples([('A', 'a'), ('B', 'b'), ('C', 'c')],names=['Column1', 'Column2'])
df = pd.DataFrame(data, index=index, columns=columns)
# 观察原始数据
df
Column1 | A | B | C |
---|---|---|---|
Column2 | a | b | c |
Index | |||
X | NaN | NaN | NaN |
Y | NaN | NaN | NaN |
Z | NaN | NaN | NaN |
- 2、默认状态下,原索引的索引名,会插入到多级列名的最顶层,即 Column1 这个层级
df8 = df.reset_index()
df8
Column1 | Index | A | B | C |
---|---|---|---|---|
Column2 | a | b | c | |
0 | X | NaN | NaN | NaN |
1 | Y | NaN | NaN | NaN |
2 | Z | NaN | NaN | NaN |
- 3、使用
col_level
参数指定 原索引的索引名,插入到Column2
层级的列名里
df9 = df.reset_index(col_level='Column2')
# df9 = df.reset_index(col_level=1) # 也可以这样,用数字层级编号指定
df9
Column1 | A | B | C | |
---|---|---|---|---|
Column2 | Index | a | b | c |
0 | X | NaN | NaN | NaN |
1 | Y | NaN | NaN | NaN |
2 | Z | NaN | NaN | NaN |
示例:当索引因重置,被插入到 DataFrame
时,指定多层列名的填充方法
- 1、构建具有多层列名的演示数据并观察层级名称
import pandas as pd
# 创建示例 DataFrame,带有多级列索引
data = {'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9], 'D':[10, 11, 12]}
index = pd.MultiIndex.from_tuples([('X'), ('Y'), ('Z')], names=['Index1'])
columns = pd.MultiIndex.from_tuples([('A', 'a', '01'), ('B', 'b', '02'), ('C', 'c', '03')],
names=['Column1', 'Column2', 'Column3'])
df = pd.DataFrame(data, index=index, columns=columns)
df
Column1 | A | B | C |
---|---|---|---|
Column2 | a | b | c |
Column3 | 01 | 02 | 03 |
Index1 | |||
X | NaN | NaN | NaN |
Y | NaN | NaN | NaN |
Z | NaN | NaN | NaN |
- 2、默认状态下,原索引的索引名,会插入到多级列名的最顶层,即 Column1 这个层级,其他层级是空的。
df9 = df.reset_index()
df9
Column1 | Index1 | A | B | C |
---|---|---|---|---|
Column2 | a | b | c | |
Column3 | 01 | 02 | 03 | |
0 | X | NaN | NaN | NaN |
1 | Y | NaN | NaN | NaN |
2 | Z | NaN | NaN | NaN |
- 3、使用
col_fill
参数,为 原索引 在其他列名层级上命名
df10 = df.reset_index(col_fill='Index1_for_others')
df10
Column1 | Index1 | A | B | C |
---|---|---|---|---|
Column2 | Index1_for_others | a | b | c |
Column3 | Index1_for_others | 01 | 02 | 03 |
0 | X | NaN | NaN | NaN |
1 | Y | NaN | NaN | NaN |
2 | Z | NaN | NaN | NaN |
示例:使用 allow_duplicates
参数控制列名不允许重复
- 1、创建演示数据并观察数据
import pandas as pd
# 创建示例 DataFrame
data = {'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9]}
df = pd.DataFrame(data)
df.set_index(['A'], inplace=True, drop=False)
# 观察原始数据
df
A | B | C | |
---|---|---|---|
A | |||
1 | 1 | 4 | 7 |
2 | 2 | 5 | 8 |
3 | 3 | 6 | 9 |
2、allow_duplicates=True
允许列名重复
df10 = df.reset_index(allow_duplicates=True)
df10
A | A | B | C | |
---|---|---|---|---|
0 | 1 | 1 | 4 | 7 |
1 | 2 | 2 | 5 | 8 |
2 | 3 | 3 | 6 | 9 |
3、allow_duplicates=False
则不允许列名重复,如果出现重复列名,会引发 ValueError
df11 = df.reset_index(allow_duplicates=False)
df11
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[48], line 1
----> 1 df11 = df.reset_index(allow_duplicates=False)
2 df11
File D:\miniconda3\envs\python3.12\Lib\site-packages\pandas\core\frame.py:6220, in DataFrame.reset_index(self, level, drop, inplace, col_level, col_fill, allow_duplicates, names)
6214 if lab is not None:
6215 # if we have the codes, extract the values with a mask
6216 level_values = algorithms.take(
6217 level_values, lab, allow_fill=True, fill_value=lev._na_value
6218 )
-> 6220 new_obj.insert(
6221 0,
6222 name,
6223 level_values,
6224 allow_duplicates=allow_duplicates,
6225 )
6227 new_obj.index = new_index
6228 if not inplace:
File D:\miniconda3\envs\python3.12\Lib\site-packages\pandas\core\frame.py:4931, in DataFrame.insert(self, loc, column, value, allow_duplicates)
4925 raise ValueError(
4926 "Cannot specify 'allow_duplicates=True' when "
4927 "'self.flags.allows_duplicate_labels' is False."
4928 )
4929 if not allow_duplicates and column in self.columns:
4930 # Should this be a different kind of error??
-> 4931 raise ValueError(f"cannot insert {column}, already exists")
4932 if not is_integer(loc):
4933 raise TypeError("loc must be int")
ValueError: cannot insert A, already exists
- 3、默认状态下,重置索引后,不允许列名存在重复 这和官方文档中的描述不一致!!
df12 = df.reset_index()
df12
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[49], line 1
----> 1 df12 = df.reset_index()
2 df12
File D:\miniconda3\envs\python3.12\Lib\site-packages\pandas\core\frame.py:6220, in DataFrame.reset_index(self, level, drop, inplace, col_level, col_fill, allow_duplicates, names)
6214 if lab is not None:
6215 # if we have the codes, extract the values with a mask
6216 level_values = algorithms.take(
6217 level_values, lab, allow_fill=True, fill_value=lev._na_value
6218 )
-> 6220 new_obj.insert(
6221 0,
6222 name,
6223 level_values,
6224 allow_duplicates=allow_duplicates,
6225 )
6227 new_obj.index = new_index
6228 if not inplace:
File D:\miniconda3\envs\python3.12\Lib\site-packages\pandas\core\frame.py:4931, in DataFrame.insert(self, loc, column, value, allow_duplicates)
4925 raise ValueError(
4926 "Cannot specify 'allow_duplicates=True' when "
4927 "'self.flags.allows_duplicate_labels' is False."
4928 )
4929 if not allow_duplicates and column in self.columns:
4930 # Should this be a different kind of error??
-> 4931 raise ValueError(f"cannot insert {column}, already exists")
4932 if not is_integer(loc):
4933 raise TypeError("loc must be int")
ValueError: cannot insert A, already exists
示例:DataFrame 被重置的索引只有1个 + 列名只有1层,传入一个字符串或整数即可
import pandas as pd
# 创建示例 DataFrame
data = {'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9]}
df = pd.DataFrame(data)
df.set_index(['A'], inplace=True, drop=False)
# 重置索引,列名改为 100
df1 = df.reset_index(names=100)
# df1 = df.reset_index(names='新列名') # 也可以使用字符串
# 查看重置后的df
df1
100 | A | B | C | |
---|---|---|---|---|
0 | 1 | 1 | 4 | 7 |
1 | 2 | 2 | 5 | 8 |
2 | 3 | 3 | 6 | 9 |
import pandas as pd
# 创建一个示例DataFrame
import pandas as pd
# 创建示例数据
data = {'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9]}
df = pd.DataFrame(data)
df.set_index(['A','B'],inplace=True)
# 重置行索引,并重传入列表命名
df2 = df.reset_index(names=['原索引1','原索引2'])
# 查看重置索引后的df
df2
原索引1 | 原索引2 | C | |
---|---|---|---|
0 | 1 | 4 | 7 |
1 | 2 | 5 | 8 |
2 | 3 | 6 | 9 |
示例: 被重置的索引只有1个 + 列名有多层,传入列表套1个元组
import pandas as pd
# 创建示例 DataFrame,带有多级列索引
data = {'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9]}
index = pd.Index(['X', 'Y', 'Z'], name='Index')
columns = pd.MultiIndex.from_tuples([('A', 'a'), ('B', 'b'), ('C', 'c')],names=['Column1', 'Column2'])
df = pd.DataFrame(data, index=index, columns=columns)
# 重置索引,并在每一个列名层级上都进行重命名
df3 = df.reset_index(names=[('顶层的新列名', '次层的新列名')])
# 观察原始数据
df3
Column1 | 顶层的新列名 | A | B | C |
---|---|---|---|---|
Column2 | 次层的新列名 | a | b | c |
0 | X | NaN | NaN | NaN |
1 | Y | NaN | NaN | NaN |
2 | Z | NaN | NaN | NaN |
示例:被重置的索引有多个 + 列名有多层,传入列表套多个元组
import pandas as pd
import numpy as np
# 创建一个示例DataFrame
index = pd.MultiIndex.from_tuples([('bird', 'falcon'),
('bird', 'parrot'),
('mammal', 'lion'),
('mammal', 'monkey')],
names=['class', 'name'])
columns = pd.MultiIndex.from_tuples([('speed', 'max'),
('species', 'type')])
df = pd.DataFrame([(389.0, 'fly'),
(24.0, 'fly'),
(80.5, 'run'),
(np.nan, 'jump')],
index=index,
columns=columns)
# 为多个被重置的索引,在多个层级的列名维度上重命名
df.reset_index(inplace=True,names=[('x1','x2'),('x3','x4')])
# 观察重置索引并重命名之后的数据
df
x1 | x3 | speed | species | |
---|---|---|---|---|
x2 | x4 | max | type | |
0 | bird | falcon | 389.0 | fly |
1 | bird | parrot | 24.0 | fly |
2 | mammal | lion | 80.5 | run |
3 | mammal | monkey | NaN | jump |