《利用Python进行数据分析》学习笔记 第11章 时间序列

第11章 时间序列

时间序列数据的意义取决于具体的应用场景,主要有以下几种:

时间戳(timestamp),特定的时刻。

固定时期(period),如2007年1月或2010年全年。

时间间隔(interval),由起始和结束时间戳表示。时期(period)可以被看做间隔(interval)的特例。

实验或过程时间,每个时间点都是相对于特定起始时间的一个度量。

11.1 日期和时间数据类型及工具

Python标准库包含用于日期(date)和时间(time)数据的数据类型,而且还有日历方面的功能。主要会用到datetime、time以及calendar模块。datetime.datetime是用得最多的数据类型: 

《利用Python进行数据分析》学习笔记 第11章 时间序列

datetime以毫秒形式存储日期和时间。timedelta表示两个datetime对象之间的时间差: 

《利用Python进行数据分析》学习笔记 第11章 时间序列

datetime模块中的数据类型: 

《利用Python进行数据分析》学习笔记 第11章 时间序列

tzinfo存储时区信息的基本类型。

  • 字符串和datetime的相互转换

利用str或strftime方法(传入一个格式化字符串),datetime对象和pandas的Timestamp对象可以被格式化为字符串: 

《利用Python进行数据分析》学习笔记 第11章 时间序列

datetime格式定义: 

《利用Python进行数据分析》学习笔记 第11章 时间序列

《利用Python进行数据分析》学习笔记 第11章 时间序列

datetime.strptime可以用这些格式化编码将字符串转换为日期: 

《利用Python进行数据分析》学习笔记 第11章 时间序列

用dateutil第三方包中的parser.parse方法不用进行日期解析时编写格式定义。 

《利用Python进行数据分析》学习笔记 第11章 时间序列

11.2 时间序列基础

不同索引的时间序列之间的算术运算会自动按日期对齐。

  • 索引、选取、子集构造

大部分时间学列数据都是按照是时间先后排序的,则可以用不存在于该时间序列中的是时间戳对其进行切片(即范围查询): 

《利用Python进行数据分析》学习笔记 第11章 时间序列

  • 带有重复索引的时间序列

要对具有非唯一时间戳的数据进行聚合。一个方法是使用groupby,并传入level=0: 

《利用Python进行数据分析》学习笔记 第11章 时间序列

11.3 日期的范围、频率以及移动

调用resample可以将之前那个时间序列转换为一个具有固定频率(每日)的时间序

列。 

《利用Python进行数据分析》学习笔记 第11章 时间序列

  • 生成日期范围

pandas.date_range用于根据指定的频率生成指定长度的DatetimeIndex: 

《利用Python进行数据分析》学习笔记 第11章 时间序列

起始和结束定义了日期索引的严格边界。例如,要生成一个由每月最后一个工作日组成的日期索引,可以传入“BM”频率(表示business end of month),这样就会包含时间间隔内(或刚好在边界上的)符合频率要求的日期:

《利用Python进行数据分析》学习笔记 第11章 时间序列

基本的时间序列频率(不完整) 

《利用Python进行数据分析》学习笔记 第11章 时间序列

《利用Python进行数据分析》学习笔记 第11章 时间序列

normalize=True可以产生被规范化的时间戳

  • 频率和日期偏移量

时间序列的基础频率: 

《利用Python进行数据分析》学习笔记 第11章 时间序列

《利用Python进行数据分析》学习笔记 第11章 时间序列

  • WOM日期

WOM(Week Of Month)非常实用的频率类,它以WOM开头,可以获得诸如“每月第3个星期五”之类的日期: 

《利用Python进行数据分析》学习笔记 第11章 时间序列

  • 移动(超前和滞后)数据

移动(shifting)指的是沿着时间轴将数据前移或后移。Series和DataFrame都有一个shift方法用于执行单纯的前移或后移操作,保持索引不变: 

《利用Python进行数据分析》学习笔记 第11章 时间序列

由于单纯的移位操作不会修改索引,所以部分数据会被丢弃。因此,如果频率已知,则可以将其传给shift以便实现对时间戳进行位移而不是对数据进行简单位移: 

《利用Python进行数据分析》学习笔记 第11章 时间序列

  • 通过偏移量对日期进行位移

pandas的日期偏移量可以用在datetime或Timestamp对象上: 

《利用Python进行数据分析》学习笔记 第11章 时间序列

通过锚点偏移量的rollforward和rollback方法,可明确地将日期向前或向后“滚动”: 

《利用Python进行数据分析》学习笔记 第11章 时间序列

11.4 时区处理

在Python中,时区信息来自第三方库pytz,它使Python可以使用Olson数据库(汇编了世界时区信息)

使用pytz.timezone从pytz中获取时区对象 

《利用Python进行数据分析》学习笔记 第11章 时间序列

  • 时区本地化和转换

从单纯到本地化的转换是通过tz_localize方法处理的。 

《利用Python进行数据分析》学习笔记 第11章 时间序列

时间序列被本地化到某个特定时区,就可以用tz_convert将其转换到别的时区了: 

《利用Python进行数据分析》学习笔记 第11章 时间序列

  • 操作时区意识型Timestamp对象

独立的Timestamp对象也能被从单纯型(naive)本地化为时区意识型(time zone-aware),并从一个时区转换到另一个时区: 

《利用Python进行数据分析》学习笔记 第11章 时间序列

时区意识型Timestamp对象在内部保存了一个UTC时间戳值,这个UTC值在时区转换过程中是不会发生变化的。

当使用pandas的DateOffset对象执行时间算术运算时,运算过程会自动关注是否存在夏令时转变期。首先是夏令时转变前的30分钟: 

《利用Python进行数据分析》学习笔记 第11章 时间序列

夏令时转变前90分钟: 

《利用Python进行数据分析》学习笔记 第11章 时间序列

  • 不同时区之间的运算
  • 如果两个时间序列的时区不同,在将它们合并到一起时,最终结果就会是UTC。 

《利用Python进行数据分析》学习笔记 第11章 时间序列

11.5 时期及其算术运算

时期(period)表示的是时间区间,比如数日、数月、数季、数年等。Period类所表示的就是这种数据类型,其构造函数需要用到一个字符串或整数。

period_range函数可用于创建规则的时期范围: 

《利用Python进行数据分析》学习笔记 第11章 时间序列

  • 时期的频率转换

Period和PeriodIndex对象都可以通过其asfreq方法被转换成别的频率。 

《利用Python进行数据分析》学习笔记 第11章 时间序列

Period频率转换示例: 

《利用Python进行数据分析》学习笔记 第11章 时间序列

《利用Python进行数据分析》学习笔记 第11章 时间序列

在将高频率转换为低频率时,超时期(superperiod)是由子时期(subperiod)所属的位置决定的。例如,在A-JUN频率中,月份“2007年8月”实际上是属于周期“2008年”的: 

《利用Python进行数据分析》学习笔记 第11章 时间序列

  • 按季度计算的时期频率

pandas支持12种可能的季度型频率,即Q-JAN到Q-DEC: 

《利用Python进行数据分析》学习笔记 第11章 时间序列

不同季度型频率之间的转换:  

《利用Python进行数据分析》学习笔记 第11章 时间序列

《利用Python进行数据分析》学习笔记 第11章 时间序列

  • 获取该季度倒数第二个工作日下午4点的时间戳: 

《利用Python进行数据分析》学习笔记 第11章 时间序列

  • 将Timestamp转换为Period(及其反向过程)

通过使用to_period方法,可以将由时间戳索引的Series和DataFrame对象转换为以时期索引: 

《利用Python进行数据分析》学习笔记 第11章 时间序列

要转换回时间戳,使用to_timestamp: 

  • 通过数组创建PeriodIndex

通过将这些数组以及一个频率传入PeriodIndex,就可以将它们合并成DataFrame的一个索引: 

《利用Python进行数据分析》学习笔记 第11章 时间序列

11.6 重采样及频率转换

重采样(resampling)指的是将时间序列从一个频率转换到另一个频率的处理过程。将高频率数据聚合到低频率称为降采样(downsampling),而将低频率数据转换到高频率则称为升采样(upsampling)。并不是所有的重采样都能被划分到这两个大类中。例如,将W-WED(每周三)转换为W-FRI既不是降采样也不是升采样。

resample方法的参数: 

《利用Python进行数据分析》学习笔记 第11章 时间序列

  • 降采样

在用resample对数据进行降采样时,需要考虑两样东西:1、各区间那边是闭合的。2、如何标记各个聚合面元,用区间的开头还是末尾。

  • 各种closed、label约定的“5分钟”重采样演示: 

《利用Python进行数据分析》学习笔记 第11章 时间序列

  • OHLC重采样

金融领域有一种无所不在的时间序列聚合方式,即计算各面元的四个值:第一个值(open,开盘)、最后一个值(close,收盘)、最大值(high,最高)以及最小值(low,最低)。传入how='ohlc'即可得到一个含有这四种聚合值的DataFrame。整个过程很高效,只需一次扫描即可计算出结果: 

《利用Python进行数据分析》学习笔记 第11章 时间序列

  • 升采样和插值

使用asfreq方法转换成高频,不经过聚合。

  • 通过时期进行重采样

由于时期指的是时间区间,所以升采样和降采样的规则就比较严格:

在降采样中,目标频率必须是源频率的子时期(subperiod)。

在升采样中,目标频率必须是源频率的超时期(superperiod)。如果不满足这些条件,就会引发异常。这主要影响的是按季、年、周计算的频率。例如,由Q-MAR定义的时间区间只能升采样为A-MAR、A-JUN、A-SEP、A-DEC等: 

《利用Python进行数据分析》学习笔记 第11章 时间序列

11.7 移动窗口函数

在移动窗口(可以带有指数衰减权数)上计算的各种统计函数也是一类常见于时间序列的数组变换。这样可以圆滑噪音数据或断裂数据。我将它们称为移动窗口函数(moving window function),其中还包括那些窗口不定长的函数(如指数加权移动平均)。跟其他统计函数一样,移动窗口函数也会自动排除缺失值。

  • 指数加权函数

另一种使用固定大小窗口及相等权数观测值的办法是,定义一个衰减因子(decay factor)常量,以便使近期的观测值拥有更大的权数。

衰减因子的定义方式主要是使用时间间隔(span),它可以使结果兼容于窗口大小等于时间间隔的简单移动窗口(simple moving window)函数。

  • 用户定义的移动窗口函数

rolling_apply函数使你能够在移动窗口上应用自己设计的数组函数。唯一要求的就是:该函数要能从数组的各个片段中产生单个值(即约简)。

比如说,当我们用rolling(…).quantile(q)计算样本分位数时,可能对样本中特定值的百分等级感兴趣。scipy.stats.percentileofscore函数就能达到这个目的:  

《利用Python进行数据分析》学习笔记 第11章 时间序列

《利用Python进行数据分析》学习笔记 第11章 时间序列