如何让Pandas按(3-4月、5-6月)规则进行双月重采样?
问题:Pandas双月重采样按偶数月末分组(3-4月、5-6月等)
我有如下每日时间序列数据:
1983-03-30 0.001224 1983-03-31 -0.003741 1983-04-04 0.005121 1983-04-05 0.009171 1983-04-06 0.006395 1983-04-07 0.009030 1983-04-08 0.006961 1983-04-11 -0.003950 1983-04-12 0.018837 1983-04-13 -0.000324 ...
尝试用双月频率重采样:
s.resample('2ME').agg('last') # 旧版Pandas请使用'2M'
得到的结果是:
1983-03-31 -0.003741 1983-05-31 0.001987 1983-07-31 0.005657 1983-09-30 -0.007843 1983-11-30 -0.005444 1984-01-31 0.003011 1984-03-31 -0.000324 1984-05-31 0.000649 1984-07-31 -0.001447 1984-09-30 0.002705
但我想要按**(3-4月)、(5-6月)、(7-8月)**这样的规则分组,最终时间戳应为:
1983-04-30 1983-06-30 1983-08-31
可通过以下代码复现场景:
import pandas as pd import numpy as np index = pd.date_range(start='1983-03-28', end='1984-01-01', freq='B') s = pd.Series(data=np.random.randn(len(index)), index=index)
请问如何实现按偶数月末分组,避免3月单独成组、4-5月为一组的情况?
解决方案
方法1:通过偏移量调整重采样起始点
Pandas的resample默认从1月开始按双月划分,我们可以用offset参数调整起始偏移,让分组从2月末开始,这样3-4月会被归为一组,最终时间戳落在偶数月末:
# 偏移1个月,让双月周期从3月开始,结束于4月末 s.resample('2ME', offset='1M').agg('last')
原理:offset='1M'把默认的起始点(1月)往后偏移1个月,第一个双月周期变为3-4月,结束于4月末,后续依次是5-6月(结束于6月末)、7-8月(结束于8月末),完全匹配需求。
方法2:手动构造分组标签(灵活自定义)
如果偏移量方式不适用,也可以手动计算每个日期的分组标签,再用groupby聚合:
def get_bimonthly_label(date): # 奇数月(3、5、7...)归属到下一个偶数月末;偶数月归属到当前月末 if date.month % 2 == 1: target_month = date.month + 1 return pd.Timestamp(year=date.year, month=target_month, day=1) - pd.Timedelta(days=1) else: return pd.Timestamp(year=date.year, month=date.month, day=1) - pd.Timedelta(days=1) + pd.DateOffset(months=1) # 按标签分组并取每组最后一个值 s.groupby(get_bimonthly_label).last()
这个方法适合需要更复杂自定义分组规则的场景。
验证结果
用复现代码测试上述方法,得到的结果时间戳会是:
1983-04-30 xxxxxxxx 1983-06-30 xxxxxxxx 1983-08-31 xxxxxxxx 1983-10-31 xxxxxxxx 1983-12-31 xxxxxxxx
完全符合预期的分组规则。
内容的提问来源于stack exchange,提问作者s5s
相关产品推荐
相关产品推荐

