python - Pandas 将每月数据重新采样为自定义频率(季节性)数据
问题描述
背景
我有一个月度数据集,并希望通过添加月度数据将其重新采样为季节性数据。
Seasonal refers to:
(Dec,Jan,Feb), (Mar,Apr,May),(June,July,Aug,Sep),(Oct,Nov)
数据
dti = pd.date_range("2015-12-31", periods=11, freq="M")
df = pd.DataFrame({'time':dti,
'data':np.random.rand(len(dti))})
Output:
time data
0 2015-12-31 0.466245
1 2016-01-31 0.959309
2 2016-02-29 0.445139
3 2016-03-31 0.575556
4 2016-04-30 0.303020
5 2016-05-31 0.591516
6 2016-06-30 0.001410
7 2016-07-31 0.338360
8 2016-08-31 0.540705
9 2016-09-30 0.115278
10 2016-10-31 0.950359
代码
因此,除了 12 月、1 月、2 月 (DJF) 之外,我能够对其他季节进行重新采样。这是我为其他季节所做的:
MAM = df.loc[df['time'].dt.month.between(3,5)].resample('Y',on='time').sum()
因为,我不能使用 DJF between
,所以我使用了条件语句。
mask = (df['time'].dt.month>11) | (df['time'].dt.month<=2)
DJF = df.loc[mask].resample('3M',origin='start',on='time').sum()
问题
即使我使用了origin = 'start'
. 所以,我的问题基本上是:
- 如何解决我的重采样问题?
- 我觉得必须有一种更直接、更简单的方法来做到这一点,而不是条件语句。另外,是否有任何类似于使用
df['time'].month.between
但用于索引的东西。我尝试使用df.index.month.between
但在 int64 日期时间对象之间不起作用。我发现重复使用df.set_index
并且df.reset_index
很烦人。
解决方案
尝试将每个月的值映射到季节值,然后groupby resample
在每个季节:
df['season'] = df['time'].dt.month.map({
12: 0, 1: 0, 2: 0,
3: 1, 4: 1, 5: 1,
6: 2, 7: 2, 8: 2, 9: 2,
10: 3, 11: 3
})
df = df.groupby('season').resample('Y', on='time')['data'].sum().reset_index()
df
:
season time data
0 0 2015-12-31 0.221993
1 0 2016-12-31 1.077451
2 1 2016-12-31 2.018766
3 2 2016-12-31 1.768848
4 3 2016-12-31 0.080741
要将上一个 12 月视为下一年的一部分,从 2015 年 12 月到 2016 年 1 月添加MonthBegin
抵消pandas.tseries.offsets
,然后将所有季节值向前调整一个月:
df['time'] = df['time'] + MonthBegin(1)
df['season'] = df['time'].dt.month.map({
1: 0, 2: 0, 3: 0,
4: 1, 5: 1, 6: 1,
7: 2, 8: 2, 9: 2, 10: 2,
11: 3, 12: 3
})
df = df.groupby('season').resample('Y', on='time')['data'].sum().reset_index()
df
:
season time data
0 0 2016-12-31 1.299445
1 1 2016-12-31 2.018766
2 2 2016-12-31 1.768848
3 3 2016-12-31 0.080741
使用的样本数据:
np.random.seed(5)
dti = pd.date_range("2015-12-31", periods=11, freq="M")
df = pd.DataFrame({'time': dti,
'data': np.random.rand(len(dti))})
df
:
time data
0 2015-12-31 0.221993
1 2016-01-31 0.870732
2 2016-02-29 0.206719
3 2016-03-31 0.918611
4 2016-04-30 0.488411
5 2016-05-31 0.611744
6 2016-06-30 0.765908
7 2016-07-31 0.518418
8 2016-08-31 0.296801
9 2016-09-30 0.187721
10 2016-10-31 0.080741
推荐阅读
- flutter - 如何在 Flutter 中显示一堆相同的小部件?
- sqlite - sqlite 提取数据集,其中一组中的不同行需要具有特定值
- google-apps-script - 如果需要,如何使用 LockService 正确等待另一个执行完成
- spring - 如何在 OAuth2 WebFlux 中设置成功和失败处理程序
- listview - 颤振选择对话框 - 将过滤器字段滚动到视图中
- sql-server - 将新行插入表中?
- amazon-web-services - AWS API Gateway - 内部访问
- python - 电报机器人向自己发送消息但不在公共组中
- html - 我如何在 explorer 11 中使用 FrameSet?
- selenium - 使用 Selenium 框架截屏时发生“TypeError: rootNode is null”