看过来
《pandas 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
时序数据分析的难点在于对时间分组的复杂性,pandas 提供了非常方法的时间重采样的接口,重采样周期可以用字符形式的别名来指定,这样就大大简化了操作,让们将分析的重点聚焦在业务分析上,而不是时间窗口的算法上。
本需求的源数据如下:
import pandas as pd
from io import StringIO
data = '''
x,y
202109,1
202110,2
202111,3
202112,4
202201,5
202202,6
202203,7
202204,8
202205,9
202206,10
202207,11
202208,12
202209,13
'''
df = pd.read_csv(StringIO(data))
df
# ...
这是一个月份数字和单纯数字组成的两列数据,需求期望我们将月份按自然半年为一个周期进行聚合分组,然后求得每个半年的数字之和。
结果的形式如下:
'''
y
x
2021下半年 10
2022上半年 45
2022下半年 36
'''
使用 pandas 的重采样工具 resample() 可以轻松实现这个时间的分组操作,在此之前要对 x 列进行数据类型转换,转为时间类型,并将其设置为索引。
计算得到结果后,就是对索引进行修改,修改为年份加上下半年字样。我们可以写一个函数并用 map 来对 Index 对象应用来完成。
先查看数据类型,发现 x 列是数字:
df.dtypes
'''
x int64
y int64
dtype: object
'''
根据数字形式表示转为时间类型:
df.x = pd.to_datetime(df.x, format='%Y%m')
df.dtypes
'''
x datetime64[ns]
y int64
dtype: object
'''
将时间列设置为索引将应用 resample() 方法进行重采样。注意,频率我们用了 Q(季度),两个 Q 为半年,再加 S 表示季度的开始时间,因为 Q 默认是结果日期。
df_temp = df.set_index('x').resample('2QS').sum()
df_temp
'''
y
x
2021-07-01 10
2022-01-01 45
2022-07-01 36
'''
重采样后,调用 sum() 方法得到了每个半年的数值之和。
接下来修改索引的值,编写一个函数让索引对象的 map 方法来映射调用。map 高阶函数传入的是索引上的每个值,这个值是时间类型的,最后返回一个处理后的值。
def rename(date: pd.Timestamp):
year = str(date.year)
if date.month==1:
return year + '上半年'
else:
return year + '下半年'
应用函数,得到最终结果:
df_temp.index = df_temp.index.map(rename)
df_temp
'''
y
x
2021下半年 10
2022上半年 45
2022下半年 36
'''
这样,我们就得到了期望的数据。
(完)
更新时间:2024-08-18 16:01:18 标签:pandas 重采样 周期