上次发了一个关于pandas多层级索引的随笔,之后就没接着往下更是到年底了有点忙之后也有点懒惰了索性就把随笔先放着。
简单介绍一下标题上的几个函数,set_index()可以把用字符串、字符串列表或数组设置为dataframe的新索引,但必须与原dataframe的长度一致;reset_index()重置dataframe的索引,重置后的索引默认是整数索引;reindex()按照给定的新索引对行/列数据进行重新排列。
import numpy as np
import pandas as pd
# 创建一个时间列表作为索引
dates = pd.Series(data=pd.date_range(start='2025-1-1',periods=10,freq='D'),name='date')
dates
0 2025-01-01
1 2025-01-02
2 2025-01-03
3 2025-01-04
4 2025-01-05
5 2025-01-06
6 2025-01-07
7 2025-01-08
8 2025-01-09
9 2025-01-10
Name: date, dtype: datetime64[ns]
# 创建dataframe
nums = np.random.randint(0,30,10)
product = [np.random.choice(['A','B','C']) for i in range(10)]
datas = list(zip(product,nums))
df = pd.DataFrame(data=datas,columns=['product','nums'])
df
product | nums | |
---|---|---|
0 | A | 26 |
1 | A | 7 |
2 | A | 19 |
3 | B | 9 |
4 | C | 29 |
5 | A | 9 |
6 | B | 17 |
7 | B | 17 |
8 | C | 28 |
9 | C | 2 |
DataFrame.set_index(keys, drop=True, append=False, inplace=False, verify_integrity=False)
● keys:字符串、字符串列表或数组类,表示要设置为索引的列名。
● drop:布尔值,默认为True。如果为True,则原DataFrame中用作新索引的列将被删除。
● append:布尔值,默认为False。如果为True,则新索引将添加到现有索引的末尾,而不是替换它。
● inplace:布尔值,默认为False。如果为True,则直接在原DataFrame上进行修改并返回None;如果为False,则返回一个新的DataFrame对象。
● verify_integrity:布尔值,默认为False。如果为True,则在设置索引之前会检查新索引是否包含重复项。
# 把日期序列作为df的新索引
df = df.set_index(dates)
df
product | nums | |
---|---|---|
date | ||
2025-01-01 | A | 26 |
2025-01-02 | A | 7 |
2025-01-03 | A | 19 |
2025-01-04 | B | 9 |
2025-01-05 | C | 29 |
2025-01-06 | A | 9 |
2025-01-07 | B | 17 |
2025-01-08 | B | 17 |
2025-01-09 | C | 28 |
2025-01-10 | C | 2 |
# 也可以把dataframe中的某一列值或多列压入到索引当中
df = df.set_index('product',append=True)
df
nums | ||
---|---|---|
date | product | |
2025-01-01 | A | 26 |
2025-01-02 | A | 7 |
2025-01-03 | A | 19 |
2025-01-04 | B | 9 |
2025-01-05 | C | 29 |
2025-01-06 | A | 9 |
2025-01-07 | B | 17 |
2025-01-08 | B | 17 |
2025-01-09 | C | 28 |
2025-01-10 | C | 2 |
这里看到虽然已经把product这一列压到索引中,但是你会发现product其实只有三个值'A','B','C',你想要以product为最高层的索引只显示A,B,C
那pandas刚好有一个函数可以把两个索引进行互换,swaplevel()
参数:
● i:要交换的第一个级别的索引。这可以是级别的名称(如果索引有名称的话)或级别的整数位置(从 0 开始计数)。
● j:要交换的第二个级别的索引。这同样可以是级别的名称或级别的整数位置。
● axis(可选):默认为 0。指定要交换级别的轴。对于 DataFrame,0 表示行索引,1 表示列索引。对于 Series,通常只涉及行索引,因此这个参数很少使用。
● copy(可选):默认为 True。如果为 False,并且交换后的索引与原始索引相同(即没有实际进行交换),则可能返回原始对象而不是其副本。然而,在大多数情况下,你应该让这个参数保持为 True,以确保返回的是一个新的对象。
● level(注意:这不是 swaplevel() 的直接参数,但在讨论多级索引时经常提到):在创建多级索引时,可以通过 level 参数为各个级别指定名称。这些名称在后续使用swaplevel() 时非常有用,因为它们允许你通过名称而不是位置来指定要交换的级别。
# 使用swaplevel让两个索引互换位置
df = df.swaplevel('date','product')
df
nums | ||
---|---|---|
product | date | |
A | 2025-01-01 | 26 |
2025-01-02 | 7 | |
2025-01-03 | 19 | |
B | 2025-01-04 | 9 |
C | 2025-01-05 | 29 |
A | 2025-01-06 | 9 |
B | 2025-01-07 | 17 |
2025-01-08 | 17 | |
C | 2025-01-09 | 28 |
2025-01-10 | 2 |
这个时候又会疑惑为什么还会有重复,这是因为A,B,C的排列顺序是随机的只有少数同样的值连续几行一起排序,那这里我们对索引进行一个排序
参数:
● axis:默认为 0。指定排序的轴。0 表示按行索引排序(即沿着列方向排序),1 表示按列索引排序(即沿着行方向排序)。
● level:可选参数。如果索引是多级的,可以通过此参数指定要排序的级别。可以是级别的名称或级别的整数位置。如果未指定,将对所有级别进行排序。
● ascending:默认为 True。指定排序的顺序。True 表示升序排序,False 表示降序排序。如果索引是多级的,可以传递一个布尔列表,为每个级别指定排序顺序。
● inplace:默认为 False。如果为 True,将在原地修改对象而不返回新的对象。如果为 False,将返回一个新的已排序对象。
● kind:指定排序算法使用的快速排序、合并排序或堆排序等。默认为 'quicksort'。对于大数据集,可能需要根据具体情况选择更适合的排序算法。
● na_position:指定缺失值(NaN)的位置。可以是 'first'(放在开头)或 'last'(放在结尾)。默认为 'last'。
● sort_remaining:当 level 参数被指定时,此参数控制是否对非指定级别进行排序。默认为 True。如果为 False,则非指定级别将保持其原始顺序。
# 对高级索引进行升序排序
df = df.sort_index(level=-2)
df
nums | ||
---|---|---|
product | date | |
A | 2025-01-01 | 26 |
2025-01-02 | 7 | |
2025-01-03 | 19 | |
2025-01-06 | 9 | |
B | 2025-01-04 | 9 |
2025-01-07 | 17 | |
2025-01-08 | 17 | |
C | 2025-01-05 | 29 |
2025-01-09 | 28 | |
2025-01-10 | 2 |
● drop:布尔值,默认为True。如果为True,则不将原索引添加为新列;如果为False,则将原索引添加为新列。
● level:整数或索引标签的列表/元组,可选。仅对多级索引(MultiIndex)有效。指定要重置的索引级别。如果不指定,则重置所有级别。
● col_level:整数或字符串,可选。如果索引被重置并且drop=False,则此参数指定新列的名称级别。通常不需要,因为默认会生成新的列名。
● col_fill:字符串,可选。当多级索引被重置且drop=False时,用于填充较低级别的列名。
● inplace:布尔值,默认为False。如果为True,则就地修改原始对象,并返回None;如果为False,则返回一个新的对象。
# 把日期序列从索引中拿出作为一列数据
df = df.reset_index(drop=False,level='date')
df
date | nums | |
---|---|---|
product | ||
A | 2025-01-01 | 26 |
A | 2025-01-02 | 7 |
A | 2025-01-03 | 19 |
A | 2025-01-06 | 9 |
B | 2025-01-04 | 9 |
B | 2025-01-07 | 17 |
B | 2025-01-08 | 17 |
C | 2025-01-05 | 29 |
C | 2025-01-09 | 28 |
C | 2025-01-10 | 2 |
# 把所有索引拿出并创建整数索引
df = df.reset_index(drop=False)
df
product | date | nums | |
---|---|---|---|
0 | A | 2025-01-01 | 26 |
1 | A | 2025-01-02 | 7 |
2 | A | 2025-01-03 | 19 |
3 | A | 2025-01-06 | 9 |
4 | B | 2025-01-04 | 9 |
5 | B | 2025-01-07 | 17 |
6 | B | 2025-01-08 | 17 |
7 | C | 2025-01-05 | 29 |
8 | C | 2025-01-09 | 28 |
9 | C | 2025-01-10 | 2 |
● index:用于指定新的行索引/标签。可以是列表、数组、Index对象或任何可迭代对象。
● columns:用于指定新的列标签(仅对DataFrame有效)。可以是列表、数组、Index对象或任何可迭代对象。
● fill_value:用于填充新索引/标签中缺失值的值(默认为NaN)。当新索引中的某些标签在原数据中不存在时,这些位置将被填充为指定的值。
● copy:布尔值,默认为True。如果为False,并且新索引与原索引完全相同,则不会复制数据。但是,请注意,即使copy=False,如果索引发生变化,数据仍然会被复制。
● level:整数或索引标签的列表/元组(仅对多级索引有效)。指定要重新索引的索引级别。
● tolerance:仅对时间索引有效。用于确定哪些索引标签被认为是“接近”的,并可以互换使用(通常用于时间数据的近似匹配)。
● sort:布尔值,默认为False。如果为True,则在新索引上对数据进行排序。但是,请注意,排序可能会增加计算成本,并且如果新索引已经是排序的,则不需要再次排序。
# 以分组的形式使值都进行聚合运算
df = df.groupby('product')['nums'].sum()
df
product
A 61
B 43
C 59
Name: nums, dtype: int32
# 我们重新对product这个索引的值进行乱序排列
new_index = ['C','A','B']
# 把乱序的列表作为dataframe的新索引且原dataframe的数据会根据之前的索引调整该行所在的顺序
df = df.reindex(new_index) # 注:使用reindex时不允许索引有重复的值
df
product
C 59
A 61
B 43
Name: nums, dtype: int32
通过上面的简单案例可以简单了解到在不同场景下该使用上面的哪一种方式对索引进行操作,如:你想要设置一个新的索引或在当前基础上加入一个新的索引就set_index();你想要重新设置整数索引或只是需要对某一级索引进行操作的就用reset_index();把一个等长的列表或数组类型的对象作为dataframe的新索引且让原有的行值按照新设置的索引进行排序就用reindex()。
最后谢谢观看,这是我学习路上的一个小记录。我会继续更新自己的一些想法和案例
参与评论
手机查看
返回顶部