时间序列:重新采样与频率转换

11.6 重新采样与频率转换

重新采样是指将时间序列从一个频率转化为另一个频率的过程。将更高频率的数据聚合到低频率称为向下采样,从低到高就是向上采样。当然,并不是所有的都是那两个,比如W-WED 转换到W-FRI 就不是向上或向下。

pandas对象有resample 方法,该方法时所有频率转换的工具函数,resample有类似goupby 的API,调用resample进行分组在调用聚合函数。

rng=pd.date_range('2000-01-01',periods=100,freq='D')
ts = pd.Series(np.random.randn(len(rng)),index=rng)
ts
2000-01-01    1.786314
2000-01-02   -0.291799
2000-01-03   -1.956842
2000-01-04    0.648374
2000-01-05   -1.181992
                ...   
2000-04-05    2.299763
2000-04-06   -0.047460
2000-04-07    0.437328
2000-04-08   -2.216516
2000-04-09   -0.504831
Freq: D, Length: 100, dtype: float64

ts.resample('M').mean()
2000-01-31   -0.233850
2000-02-29   -0.106162
2000-03-31   -0.226881
2000-04-30    0.034787
Freq: M, dtype: float64

ts.resample('M',kind='period').size()
2000-01    31
2000-02    29
2000-03    31
2000-04     9
Freq: M, dtype: int64

resample 是一个灵活且高能的方法,用于处理大型时间序列。

resample参数描述
freq喵喵所需采样频率的字符串或dateoffset对象(例如M 5min, Second(1))
axis需要采样的轴向,默认axis=0
fill_method向上采样时的插值方式,开始ffill or bfill,默认不插值
closed向下采样中,每段间隔的那一段时封闭的,right or left
label向下采样中,如果用right or left 的箱标签标记聚合结果(例如,9:30 到 9:35 的每分钟间隔可用标记为9:30 or 9"35)
loffset对箱标签进行时间调教,例如 ‘ -1s’ /Second(-1) 可以将聚合标签向前移动一秒
limit向前或向后填充时,填充区间啊的最大值
kind对区间(‘period’) 或时间戳(timestamp) 的聚合,默认是时间序列索引的类型
convention在对区间重新采样时,用于将低频周期转换为高频的约定(start or end),默认 end

11.6.1 向下采样

将数据聚合到一个规则的低频率上。你要聚合的数据不必是固定频率的。期望的频率定义了用于对时间序列切以聚合和的箱体边界。例如,要将时间转换为每月,M orMB ,你需要将数据分成一个月的时间间隔,每个间隔都是半闭合的,一个数据点只能属于一个间隔,时间间隔的并集必须是整个时间帧,现在使用resample 进行向下采样数据是要考虑:

  • 每段间隔那一边是闭合的
  • 如何在间隔的起始或结束位置标记每个已聚合的箱体。
rng = pd.date_range('2000-01-01', periods=12, freq='T')
ts = pd.Series(np.arange(12), index=rng)
ts
2000-01-01 00:00:00     0
2000-01-01 00:01:00     1
2000-01-01 00:02:00     2
2000-01-01 00:03:00     3
2000-01-01 00:04:00     4
2000-01-01 00:05:00     5
2000-01-01 00:06:00     6
2000-01-01 00:07:00     7
2000-01-01 00:08:00     8
2000-01-01 00:09:00     9
2000-01-01 00:10:00    10
2000-01-01 00:11:00    11
Freq: T, dtype: int32

ts.resample('5min',closed='right').sum()      # 通过计算每一组的和将这些数据聚合到五分钟的块内。
1999-12-31 23:55:00     0
2000-01-01 00:00:00    15      # 这里按五分钟的增量定义了箱体边界,默认是左包含,00:00包含在00:00 00:05间隔内。
2000-01-01 00:05:00    40      # 由于传递了right 就变成了右包含。00:00 包含在23:55 :00:00 内
2000-01-01 00:10:00    11
Freq: 5T, dtype: int32

ts.resample('5min', closed='right', label='right').sum()  # 产生的时间序列按照每个箱体左边的时间戳被标记
2000-01-01 00:00:00     0                          # 传递label =right可以使用右箱体编辑标记时间序列。
2000-01-01 00:05:00    15                   # 就是把右边那个边界当作了这个箱的标签。。。
2000-01-01 00:10:00    40
2000-01-01 00:15:00    11
Freq: 5T, dtype: int32

在这里插入图片描述
最后需要改将结果索引移动一定的数量,例如从右边缘减去一秒,以使其更清楚的表明时间戳所致的间隔。使用loffset 传递字符串或日期偏置

ts.resample('5min', closed='right',
            label='right', loffset='-1s').sum()
1999-12-31 23:59:59     0
2000-01-01 00:04:59    15
2000-01-01 00:09:59    40
2000-01-01 00:14:59    11
Freq: 5T, dtype: int32           # 也可以在结果上调用shift 来完成loffset的效果。
11.6.1.1 开端-峰值-谷值-结束(OHLC)重新采样

金融中,每个数据桶计算四个值使一种流行的时间序列聚合方法:第一个/最后一个值,最大值/最小值。通过使用ohlc 聚合函数将会获得这四种列的dataframe, 这些值在数据的单次扫描中被高效计算。

ts.resample('5min').ohlc()

                open	high	low	close
2000-01-01 00:00:00	0	4	0	4
2000-01-01 00:05:00	5	9	5	9
2000-01-01 00:10:00	10	11	10	11

11.6.2 向上采样与插值

低频率转换为高频率,不用聚合。

frame = pd.DataFrame(np.random.randn(2, 4),
                     index=pd.date_range('1/1/2000', periods=2,
                                         freq='W-WED'),
                     columns=['Colorado', 'Texas', 'New York', 'Ohio'])
frame
	Colorado	Texas	New York	Ohio
2000-01-05	-2.645128	0.046365	2.081303	-0.269813
2000-01-12	0.628091	-0.796716	0.745522	0.543738               # 这是每周数据

# 当你对这数据使用聚合函数时,每一组只有一个值,其他的就是缺失值。使用asfeq 方法在不聚合的情况下转换到高频率。
df_daily = frame.resample('D').asfreq()
df_daily
            Colorado	Texas	New York	Ohio
2000-01-05	-2.645128	0.046365	2.081303	-0.269813
2000-01-06	NaN	NaN	NaN	NaN
2000-01-07	NaN	NaN	NaN	NaN
2000-01-08	NaN	NaN	NaN	NaN
2000-01-09	NaN	NaN	NaN	NaN
2000-01-10	NaN	NaN	NaN	NaN
2000-01-11	NaN	NaN	NaN	NaN
2000-01-12	0.628091	-0.796716	0.745522	0.543738

frame.resample('D').ffill(limit=2)         # 向前填充,限制两层
	Colorado	Texas	New York	Ohio
2000-01-05	-2.645128	0.046365	2.081303	-0.269813
2000-01-06	-2.645128	0.046365	2.081303	-0.269813
2000-01-07	-2.645128	0.046365	2.081303	-0.269813
2000-01-08	NaN	NaN	NaN	NaN
2000-01-09	NaN	NaN	NaN	NaN
2000-01-10	NaN	NaN	NaN	NaN
2000-01-11	NaN	NaN	NaN	NaN
2000-01-12	0.628091	-0.796716	0.745522	0.543738

frame.resample('W-THU').ffill()           # 新的入侵索引不需要u旧的索引重叠。
	Colorado	Texas	New York	Ohio
2000-01-06	-2.645128	0.046365	2.081303	-0.269813
2000-01-13	0.628091	-0.796716	0.745522	0.543738

11.6.3 使用区间进行重新采样

与时间戳的情况类似:

frame = pd.DataFrame(np.random.randn(24, 4),
                     index=pd.period_range('1-2000', '12-2001',
                                           freq='M'),
                     columns=['Colorado', 'Texas', 'New York', 'Ohio'])
frame[:5]
	Colorado	Texas	New York	Ohio
2000-01	-1.717227	-0.760344	-0.765159	0.169781
2000-02	-2.126560	-0.111980	0.638584	-0.165626
2000-03	-0.022074	0.712966	0.119652	0.926564
2000-04	0.579960	1.233219	-0.245011	-0.520845
2000-05	0.621369	-0.581604	-1.582550	-0.155883


annual_frame = frame.resample('A-DEC').mean()
annual_frame
Colorado	Texas	New York	Ohio
2000	-0.031077	-0.245267	0.181879	0.301356
2001	0.139282	-0.164084	0.004472	0.167112

向上采集更加细致,因为i你要在重新采集前决定新频率在时间段的那一段放置数值,就像asfreq 方法一样,convention参数默认时start ,可以时end

# Q-DEC: 季度末在12月
annual_frame.resample('Q-DEC').ffill()

Colorado	Texas	New York	Ohio
2000Q1	-0.031077	-0.245267	0.181879	0.301356
2000Q2	-0.031077	-0.245267	0.181879	0.301356
2000Q3	-0.031077	-0.245267	0.181879	0.301356
2000Q4	-0.031077	-0.245267	0.181879	0.301356
2001Q1	0.139282	-0.164084	0.004472	0.167112
2001Q2	0.139282	-0.164084	0.004472	0.167112
2001Q3	0.139282	-0.164084	0.004472	0.167112
2001Q4	0.139282	-0.164084	0.004472	0.167112

annual_frame.resample('Q-DEC', convention='end').ffill()   # 按我理解就是convention=start时,以2000.2001这两年的Q1放
Colorado	Texas	New York	Ohio					 # 数据,之间的向前填充
2000Q4	-0.031077	-0.245267	0.181879	0.301356	# 为end 时,Q4 放数据,2000Q4之前的就没有填充值了,,,
2001Q1	-0.031077	-0.245267	0.181879	0.301356
2001Q2	-0.031077	-0.245267	0.181879	0.301356
2001Q3	-0.031077	-0.245267	0.181879	0.301356        # 仔细想想还是可以看懂的。。。
2001Q4	0.139282	-0.164084	0.004472	0.167112

区间设及时间范围,向上和向下采样旧更加严格

  • 在向下采集中,目标频率必须是原频率的子区间
  • 在向上采集中,目标频率必须时原频率的父区间
    如果不满足就会引发异常。这主要会影响每季度,每年,每周的频率。例如:Q-MAR定义的时间范围将只和A-MAR,A-JUN A-SEP A-DEC保存一致
annual_frame.resample('Q-MAR').ffill()

Colorado	Texas	New York	Ohio
2000Q4	-0.031077	-0.245267	0.181879	0.301356
2001Q1	-0.031077	-0.245267	0.181879	0.301356
2001Q2	-0.031077	-0.245267	0.181879	0.301356
2001Q3	-0.031077	-0.245267	0.181879	0.301356
2001Q4	0.139282	-0.164084	0.004472	0.167112
2002Q1	0.139282	-0.164084	0.004472	0.167112
2002Q2	0.139282	-0.164084	0.004472	0.167112
2002Q3	0.139282	-0.164084	0.004472	0.167112
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值