当前位置: 首页 > article >正文

pandas教程:Resampling and Frequency Conversion 重采样和频度转换

文章目录

  • 11.6 Resampling and Frequency Conversion(重采样和频度转换)
  • 1 Downsampling(降采样)
      • Open-High-Low-Close (OHLC) resampling(股价图重取样)
  • 2 Upsampling and Interpolation(增采样和插值)
  • 3 Resampling with Periods(对周期进行重采样)

11.6 Resampling and Frequency Conversion(重采样和频度转换)

重采样(Resampling)指的是把时间序列的频度变为另一个频度的过程。把高频度的数据变为低频度叫做降采样(downsampling),把低频度变为高频度叫做增采样(upsampling)。并不是所有的重采样都会落入上面这几个类型,例如,把W-WED(weekly on Wednesday)变为W-FRI`,既不属于降采样,也不属于增采样。

pandas对象自带resample方法,用于所有的频度变化。resample有一个和groupby类似的API;我们可以用resample来对数据进行分组,然后调用聚合函数(aggregation function):

import numpy as np
import pandas as pd
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    0.141136
2000-01-02    0.955511
2000-01-03   -0.334537
2000-01-04    0.927611
2000-01-05    0.522567
2000-01-06    0.843023
2000-01-07    0.108661
2000-01-08    0.805668
2000-01-09   -0.470524
2000-01-10    1.162150
2000-01-11   -0.754087
2000-01-12   -1.846421
2000-01-13   -0.322607
2000-01-14    0.769992
2000-01-15   -0.596838
2000-01-16    0.865629
2000-01-17   -0.394363
2000-01-18    1.050334
2000-01-19    0.203739
2000-01-20    0.112178
2000-01-21   -1.858528
2000-01-22    0.921361
2000-01-23   -1.034003
2000-01-24   -0.319369
2000-01-25    0.626385
2000-01-26    2.319831
2000-01-27    0.640064
2000-01-28    0.762187
2000-01-29   -0.053246
2000-01-30    0.500993
                ...   
2000-03-11   -1.036658
2000-03-12    0.569500
2000-03-13   -0.279623
2000-03-14   -1.593708
2000-03-15   -1.552634
2000-03-16    0.983931
2000-03-17    0.269289
2000-03-18    0.870814
2000-03-19    1.642178
2000-03-20   -0.109097
2000-03-21   -1.891613
2000-03-22   -1.867747
2000-03-23   -0.173888
2000-03-24    0.879418
2000-03-25    0.814583
2000-03-26   -1.683395
2000-03-27   -0.141228
2000-03-28    0.392206
2000-03-29   -1.288983
2000-03-30    1.052897
2000-03-31   -0.297663
2000-04-01    1.050265
2000-04-02   -0.072390
2000-04-03    1.482098
2000-04-04   -0.276297
2000-04-05    0.686525
2000-04-06    1.368484
2000-04-07    0.294756
2000-04-08    1.237246
2000-04-09    1.372567
Freq: D, dtype: float64
ts.resample('M').mean()
2000-01-31   -0.207554
2000-02-29    0.299003
2000-03-31   -0.095402
2000-04-30   -0.146846
Freq: M, dtype: float64
ts.resample('M', kind='period').mean()
2000-01    0.210165
2000-02   -0.051811
2000-03   -0.131131
2000-04    0.793695
Freq: M, dtype: float64

resample是一个灵活且高效的方法,可以用于处理大量的时间序列。

1 Downsampling(降采样)

把数据聚合为规律、低频度是一个很普通的时间序列任务。用于处理的数据不必是有固定频度的;我们想要设定的频度会定义箱界(bin edges),根据bin edges会把时间序列分割为多个片段,然后进行聚合。例如,转换为月度,比如'M''BM',我们需要把数据以月为间隔进行切割。每一个间隔都是半开放的(half-open);一个数据点只能属于一个间隔,所有间隔的合集,构成整个时间范围(time frame)。当使用resample去降采样数据的时候,有很多事情需要考虑:

  • 在每个间隔里,哪一边要闭合
  • 怎样对每一个聚合的bin贴标签,可以使用间隔的开始或结束

为了演示一下,下面用一个一分钟的数据来举例:

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: int64

假设我们想要按5分钟一个数据块来进行聚合,然后对每一个组计算总和:

ts.resample('5min', closed='right').sum()
1999-12-31 23:55:00     0
2000-01-01 00:00:00    15
2000-01-01 00:05:00    40
2000-01-01 00:10:00    11
Freq: 5T, dtype: int64

我们传入的频度定义了每个bin的边界按5分钟递增。默认,bin的左边界是闭合的,所以00:00值是属于00:0000:05间隔的。设定closed='right',会让间隔的右边闭合:

ts.resample('5min', closed='right').sum()
1999-12-31 23:55:00     0
2000-01-01 00:00:00    15
2000-01-01 00:05:00    40
2000-01-01 00:10:00    11
Freq: 5T, dtype: int64

默认,每一个bin的左边的时间戳,会被用来作为结果里时间序列的标签。通过设置label='right',我们可以使用bin右边的时间戳来作为标签:

ts.resample('5min', closed='right', label='right').sum()
2000-01-01 00:00:00     0
2000-01-01 00:05:00    15
2000-01-01 00:10:00    40
2000-01-01 00:15:00    11
Freq: 5T, dtype: int64

最后,我们可能想要对结果的索引进行位移,比如在右边界减少一秒。想要实现的话,传递一个字符串或日期偏移给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: int64

我们也可以使用shift方法来实现上面loffset的效果。

Open-High-Low-Close (OHLC) resampling(股价图重取样)

Open-High-Low-Close: 开盘-盘高-盘低-收盘图;股票图;股价图

在经济界,一个比较流行的用法,是对时间序列进行聚合,计算每一个桶(bucket)里的四个值:first(open),last(close),maximum(high),minimal(low),即开盘-收盘-盘高-盘低,四个值。使用ohlc聚合函数可以得到这四个聚合结果:

ts.resample('5min').ohlc()
openhighlowclose
2000-01-01 00:00:000404
2000-01-01 00:05:005959
2000-01-01 00:10:0010111011

2 Upsampling and Interpolation(增采样和插值)

把一个低频度转换为高频度,是不需要进行聚合的。下面是一个有周数据的DataFrame

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
ColoradoTexasNew YorkOhio
2000-01-050.1383551.8815170.6553671.496932
2000-01-12-1.125212-0.8243370.803721-0.672660

当我们对这个数据进行聚合的的时候,每个组只有一个值,以及gap(间隔)之间的缺失值。在不使用任何聚合函数的情况下,我们使用asfreq方法将其转换为高频度:

df_daily = frame.resample('D').asfreq()
df_daily
ColoradoTexasNew YorkOhio
2000-01-050.1383551.8815170.6553671.496932
2000-01-06NaNNaNNaNNaN
2000-01-07NaNNaNNaNNaN
2000-01-08NaNNaNNaNNaN
2000-01-09NaNNaNNaNNaN
2000-01-10NaNNaNNaNNaN
2000-01-11NaNNaNNaNNaN
2000-01-12-1.125212-0.8243370.803721-0.672660

假设我们想要用每周的值来填写非周三的部分。这种方法叫做填充(filling)或插值(interpolation),可以使用fillnareindex方法来实现重采样:

frame.resample('D').ffill()
ColoradoTexasNew YorkOhio
2000-01-050.1383551.8815170.6553671.496932
2000-01-060.1383551.8815170.6553671.496932
2000-01-070.1383551.8815170.6553671.496932
2000-01-080.1383551.8815170.6553671.496932
2000-01-090.1383551.8815170.6553671.496932
2000-01-100.1383551.8815170.6553671.496932
2000-01-110.1383551.8815170.6553671.496932
2000-01-12-1.125212-0.8243370.803721-0.672660

我们可以选择只对一部分的周期进行填写:

frame.resample('D').ffill(limit=2)
ColoradoTexasNew YorkOhio
2000-01-050.1383551.8815170.6553671.496932
2000-01-060.1383551.8815170.6553671.496932
2000-01-070.1383551.8815170.6553671.496932
2000-01-08NaNNaNNaNNaN
2000-01-09NaNNaNNaNNaN
2000-01-10NaNNaNNaNNaN
2000-01-11NaNNaNNaNNaN
2000-01-12-1.125212-0.8243370.803721-0.672660

注意,新的日期索引不能与旧的有重叠:

frame.resample('W-THU').ffill()
ColoradoTexasNew YorkOhio
2000-01-060.1383551.8815170.6553671.496932
2000-01-13-1.125212-0.8243370.803721-0.672660

3 Resampling with Periods(对周期进行重采样)

对周期的索引进行重采样的过程,与之前时间戳的方法相似:

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]
ColoradoTexasNew YorkOhio
2000-011.4510950.236027-1.1147851.245450
2000-021.720449-0.724853-1.8706761.089338
2000-030.411774-0.7859791.7490240.164739
2000-04-1.549051-0.0507220.002775-1.606657
2000-051.0119980.149377-1.6082620.992927
annual_frame = frame.resample('A-DEC').mean()
annual_frame
ColoradoTexasNew YorkOhio
20000.208662-0.109971-0.2334640.138465
2001-0.4019460.368050-0.209196-0.155851

增采样需要考虑的要多一些,比如在重采样前,选择哪一个时间跨度作为结束,就像asfreq方法那样。convertion参数默认是'start',但也能用'end'

# Q-DEC: Quarterly, year ending in December
annual_frame.resample('Q-DEC').ffill()
ColoradoTexasNew YorkOhio
2000Q10.208662-0.109971-0.2334640.138465
2000Q20.208662-0.109971-0.2334640.138465
2000Q30.208662-0.109971-0.2334640.138465
2000Q40.208662-0.109971-0.2334640.138465
2001Q1-0.4019460.368050-0.209196-0.155851
2001Q2-0.4019460.368050-0.209196-0.155851
2001Q3-0.4019460.368050-0.209196-0.155851
2001Q4-0.4019460.368050-0.209196-0.155851
annual_frame.resample('Q-DEC', convention='end').ffill()
ColoradoTexasNew YorkOhio
2000Q40.208662-0.109971-0.2334640.138465
2001Q10.208662-0.109971-0.2334640.138465
2001Q20.208662-0.109971-0.2334640.138465
2001Q30.208662-0.109971-0.2334640.138465
2001Q4-0.4019460.368050-0.209196-0.155851

增采样和降采样的规则更严格一些:

  • 降采样中,目标频度必须是原频度的子周期(subperiod
  • 增采样中,目标频度必须是原频度的母周期(superperiod

如果不满足上面的规则,会报错。主要会影响到季度,年度,周度频度;例如,用Q-MAR定义的时间跨度只与A-MAR, A-JUN, A-SEP, A-DEC进行对齐(line up with):

annual_frame.resample('Q-MAR').ffill()
ColoradoTexasNew YorkOhio
2000Q40.208662-0.109971-0.2334640.138465
2001Q10.208662-0.109971-0.2334640.138465
2001Q20.208662-0.109971-0.2334640.138465
2001Q30.208662-0.109971-0.2334640.138465
2001Q4-0.4019460.368050-0.209196-0.155851
2002Q1-0.4019460.368050-0.209196-0.155851
2002Q2-0.4019460.368050-0.209196-0.155851
2002Q3-0.4019460.368050-0.209196-0.155851

http://www.kler.cn/a/133285.html

相关文章:

  • NFS-Ganesha 核心架构解读
  • 【环境配置】macOS配置jdk与maven
  • NVMe(Non-Volatile Memory Express)非易失性存储器访问和传输协议
  • Uniapp踩坑input自动获取焦点ref动态获取实例不可用
  • 从0开始学习--Day26--聚类算法
  • 前端学习八股资料CSS(二)
  • Flask学习一:概述
  • IntelliJ IDE 插件开发 |(一)快速入门
  • CentOS7安装xvfb,解决服务器没有X-Server的问题
  • springboot+activiti5.22.0集成Activiti在线流程设计器
  • 数据结构-插入排序实现
  • CCRC认证是什么?
  • JVM 调优指南
  • 视频会议设备如何安装?
  • 机器学习笔记 - 使用 PyTorch 的多任务学习和 HydraNet
  • SpringBoot-----从前端更新数据到MySql数据库
  • Android问题笔记四十六:解决open failed: EACCES (Permission denied) 问题
  • Scrapy----Scrapy简介
  • 记录一次较为完整的服务打包发布流程
  • Java中,ArrayList和LinkedList区别区分,简洁
  • Navicat 基于 GaussDB 主备版的快速入门
  • 第七部分:Maven(项目管理工具)
  • Linux每日智囊-cat, more, less
  • 【DevOps】Git 图文详解(一):简介及基础概念
  • javascript选择器的封装,只需要写元素名或css类及id都可以选择到元素
  • pipeline jenkins流水线