关于Pandas版本: 本文基于 pandas2.2.0 编写。
关于本文内容更新: 随着pandas的stable版本更迭,本文持续更新,不断完善补充。
本节目录
- Pandas.DataFrame.set_index()
- 语法:
- 返回值:
- 参数说明:
- keys 指定作为索引的列
- drop 是否舍弃作为索引的列
- append 追加 / 替换
- inplace 原地生效
- verify_integrity 唯一性验证
- 相关方法:
- 示例:
Pandas.DataFrame.set_index()
pandas.DataFrame.set_index
方法用于为 DataFrame
添加索引(行标签)。
- 新索引可以来自于
DataFrame
现有的列;例 - 也可以来自于外 array-like 对象;例
- 也可以来自于其他
index
(索引对象)。
语法:
DataFrame.set_index(keys, * , drop=True, append=False, inplace=False, verify_integrity=False)
返回值:
- DataFrame or None
如果inplace
设置为True
则返回None
否则返回一个新的DataFrame
。
参数说明:
keys 指定作为索引的列
- keys:label or array-like or list of labels/arrays
指定要设置为索引的列名或列名的列表。
- label: 可以传递单个
DataFrame
中的某个列名。例 - list of labels/arrays:
- 由
DataFrame
中现有的多个列名组成的列表;例 - 多个外部 array-like 对象组成的列表。例
- array-like: 可以传递来自外部的 array-like 对象。例
⚠️ 注意 :
- 不可以直接把外部的
列表对象(list)
传递给keys
参数,否则会引发KeyError:
错误。- 可以尝试先把这个列表转换为
ndarray
或Series
,再传递给keys
参数。例
drop 是否舍弃作为索引的列
- drop:bool, default True
当使用DataFrame
中的列作为索引时,drop
参数控制是否在数据区域保留该列。
- 默认为
True
,表示将指定的列从DataFrame
中删除并设置为索引。 - 如果设置为
False
,则保留指定的列作为普通列,同时创建一个新的索引列。例
append 追加 / 替换
- append:bool, default False
append
参数控制添加索引时候,是否移除原来的索引:
- 默认为
False
,表示替换现有的索引。 - 如果设置为
True
,则将新的索引列附加到现有的索引列中,和原索引组成多层索引。例
inplace 原地生效
- inplace:bool, default False
inplace
参数控制着是否让修改在原DataFrame
内生效:
- 默认为
False
,表示返回一个新的DataFrame
,而不修改原始的DataFrame
。 - 如果设置为
True
,则在原始DataFrame
上进行就地修改,并返回None
。 例
verify_integrity 唯一性验证
- verify_integrity : bool, default False
默认为False
,表示不验证新的索引是否唯一。如果设置为True
,则会验证新的索引是否唯一,如果存在重复值,将引发异常。
相关方法:
➡️ 相关方法
- DataFrame.reset_index重置索引(重置为数字索引)。
- DataFrame.reindex重索引
- DataFrame.reindex_like仿制索引
示例:
测试文件下载:
本文所涉及的测试文件,如有需要,可在文章顶部的绑定资源处下载。
若发现文件无法下载,应该是资源包有内容更新,正在审核,请稍后再试。或站内私信作者索要。
示例:传入单个列名,指定一个列作为索引
- 1、构建演示数据,并观察原始索引
import pandas as pd
# 创建一个示例DataFrame
data = {'A': [1, 2, 3], 'B': [4, 5, 6], 'C':[7, 8, 9]}
df = pd.DataFrame(data)
# 观察df
df
A | B | C | |
0 | 1 | 4 | 7 |
1 | 2 | 5 | 8 |
2 | 3 | 6 | 9 |
2、将 A 列作为索引,并观察修改索引后的df
# 将'A'设置为索引列
df.set_index('A', inplace=True)
# 观察修改索引后的df
df
B | C | |
A | ||
1 | 4 | 7 |
2 | 5 | 8 |
3 | 6 | 9 |
示例:传入多个列名,指定多列组成多层索引
- 1、构建演示数据,并观察原始索引
- 注意!使用列表传入多个列名,列表里的列名,必须包含在
DataFrame
的列名中!
import pandas as pd
# 创建一个示例DataFrame
data = {'A': [1, 2, 3], 'B': [4, 5, 6], 'C':[7, 8, 9], 'D':[10, 11, 12]}
df = pd.DataFrame(data)
# 观察df
df
A | B | C | D | |
0 | 1 | 4 | 7 | 10 |
1 | 2 | 5 | 8 | 11 |
2 | 3 | 6 | 9 | 12 |
2、传入多个列名的列表,组成多层索引
# 传入多个列名的列表,组成多层索引
df.set_index(['A','B'],inplace=True)
# 观察修改后的df
df
C | D | ||
A | B | ||
1 | 4 | 7 | 10 |
2 | 5 | 8 | 11 |
3 | 6 | 9 | 12 |
示例:用 DataFrame
外部的 array-like
对象作为新索引
注意!虽然 列表(list)对象,也是 array-like
,但是在 DataFrame.set_index
中,不能直接传递列表,必须先转换为 ndarray
或 Series
。
- 1、 创建演示数据,并观察原始数据的索引
import pandas as pd
import numpy as np
# 创建一个示例DataFrame
data = {'A': [1, 2, 3], 'B': [4, 5, 6]}
df = pd.DataFrame(data)
# 观察原始数据
df
A | B | |
0 | 1 | 4 |
1 | 2 | 5 |
2 | 3 | 6 |
- 2、创建一个
Series
并将其设置为DataFrame
的索引,并观察更新后的DataFrame
。
# 构建一个列表
data_for_series = ['row1', 'row2', 'row3']
# 把列表转为Series
s = pd.Series(data_for_series,name='new_index_from_series')
# 把这个Series作为DataFrame的新索引
df.set_index(s, inplace=True)
# 观察更新索引后的df
df
A | B | |
new_index_from_series | ||
row1 | 1 | 4 |
row2 | 2 | 5 |
row3 | 3 | 6 |
- 3、创建一个
ndarray
并将其设置为DataFrame
的索引,并观察更新后的DataFrame
。
# 构建一个列表
data_for_series = ['nrow1', 'nrow2', 'nrow3']
# 把列表转为Series
s = pd.Series(data_for_series,name='new_index_from_ndarray')
# 把这个Series作为DataFrame的新索引
df.set_index(s, inplace=True)
# 观察更新索引后的df
df
A | B | |
new_index_from_ndarray | ||
nrow1 | 1 | 4 |
nrow2 | 2 | 5 |
nrow3 | 3 | 6 |
示例:传入多个外部的 array-like
对象,组成多层索引,仅以 Series
为例,其他类型的array-like
对象请自行尝试。
- 1、 创建演示数据,并观察原始数据的索引
import pandas as pd
# 创建一个示例DataFrame
data = {'A': [1, 2, 3], 'B': [4, 5, 6], 'C':[7, 8, 9], 'D':[10, 11, 12]}
df = pd.DataFrame(data)
# 观察df
df
A | B | C | D | |
0 | 1 | 4 | 7 | 10 |
1 | 2 | 5 | 8 | 11 |
2 | 3 | 6 | 9 | 12 |
- 2、创建多个Series,组成列表后,传递给set_index,组成多层索引
# 构建数据
data1 = ['a', 'b', 'c']
data2 = ['tony', 'mike', 'joo']
# 构建Series
s1 = pd.Series(data1,name='第1层')
s2 = pd.Series(data2,name='第2层')
# 传递给set_index,组成多层索引
df.set_index([s1,s2], inplace=True)
# 观察更新索引后的df
df
A | B | C | D | ||
第1层 | 第2层 | ||||
a | tony | 1 | 4 | 7 | 10 |
b | mike | 2 | 5 | 8 | 11 |
c | joo | 3 | 6 | 9 | 12 |
示例:指定DataFrame内部某列作为索引,同时保留该列作为普通数据列
import pandas as pd
# 创建一个示例DataFrame
data = {'A': [1, 2, 3], 'B': [4, 5, 6], 'C':[7, 8, 9], 'D':[10, 11, 12]}
df = pd.DataFrame(data)
# 使用D列作为索引,但是同时也需要将其保留为普通数据列
df.set_index('D', drop=False, inplace=True)
# 观察修改索引之后的df
df
A | B | C | D | |
D | ||||
10 | 1 | 4 | 7 | 10 |
11 | 2 | 5 | 8 | 11 |
12 | 3 | 6 | 9 | 12 |
示例:保留原索引,与新索引组成多层索引
import pandas as pd
# 创建一个示例DataFrame
data = {'A': [1, 2, 3], 'B': [4, 5, 6], 'C':[7, 8, 9], 'D':[10, 11, 12]}
df = pd.DataFrame(data)
# 使用D列作为索引,保留原索引
df.set_index('D', append=True, inplace=True)
# 观察修改索引之后的df
df
A | B | C | ||
D | ||||
0 | 10 | 1 | 4 | 7 |
1 | 11 | 2 | 5 | 8 |
2 | 12 | 3 | 6 | 9 |
示例: inplace参数的影响
- 1、默认状态下,
DataFrame.set_index()
不会在原DataFrame
添加索引,而是生成一个添加了索引的新的DataFrame
对象。
import pandas as pd
# 创建一个示例DataFrame
data = {'A': [1, 2, 3], 'B': [4, 5, 6], 'C':[7, 8, 9], 'D':[10, 11, 12]}
df = pd.DataFrame(data)
# 使用D列作为索引
df.set_index('D')
# 观察df
df
A | B | C | D | |
0 | 1 | 4 | 7 | 10 |
1 | 2 | 5 | 8 | 11 |
2 | 3 | 6 | 9 | 12 |
可以发现,虽然为df添加了索引,但是并没有直接在原来的df里生效。
- 2、将
inplace
参数设置为True
,则会使修改在原DataFrame
生效。
# 使用D列作为索引,将 inplace 参数设置为 True ,则会使修改在原 DataFrame 生效。
df.set_index('D', inplace=True)
# 观察df
df
A | B | C | |
D | |||
10 | 1 | 4 | 7 |
11 | 2 | 5 | 8 |
12 | 3 | 6 | 9 |
可以发现,当inplace 参数设置为 True ,则会使修改在原 DataFrame 生效。
示例:限制新索引的唯一性
如果对新索引的唯一性有严格的要求,可以在设置索引时使用 verify_integrity
参数进行限制。新索引没有重复值的情况下可以成功,否则会引发报错。
import pandas as pd
# 创建一个示例DataFrame
data = {'A': [1, 2, 3], 'B': [4, 5, 6], 'C':[7, 8, 9], 'D':[10, 10, 11]}
df = pd.DataFrame(data)
# 使用D列作为索引
df.set_index('D', inplace=True, verify_integrity=True)
# 观察df
df
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[36], line 7
4 df = pd.DataFrame(data)
6 # 使用D列作为索引
----> 7 df.set_index('D', inplace=True, verify_integrity=True)
9 # 观察df
10 df
File D:\miniconda3\envs\python3.12\Lib\site-packages\pandas\core\frame.py:5930, in DataFrame.set_index(self, keys, drop, append, inplace, verify_integrity)
5928 if verify_integrity and not index.is_unique:
5929 duplicates = index[index.duplicated()].unique()
-> 5930 raise ValueError(f"Index has duplicate keys: {duplicates}")
5932 # use set to handle duplicate column names gracefully in case of drop
5933 for c in set(to_remove):
ValueError: Index has duplicate keys: Index([10], dtype='int64', name='D')
可以发现,当 verify_integrity=True
的时候, 由于 D列[10, 10, 11]存在重复值,导致在使用D列作为新索引时引发了 `ValueError``