【时间序列分析】S04E02时间序列索引的表示方法

0.本集概览

1.pandas时间序列的基本表示
2.时间戳数据类型及索引结构
3.时间周期数据及索引结构
4.时间增量数据及索引结构
5.关于时间频率的问题

在上一节中,我们分别介绍了如何利用python原生工具、numpy和pandas这三种工具进行时间的表示和基本操作。而pandas作为时间和日期类数据操作的最佳解决方案,将是我们这一季后续内容中的主要学习目标和使用工具。

1.pandas时间序列的基本表示

我们在之前讲过,时间序列其实和原来介绍过的一般序列没有什么本质的不同,唯一的区别就是他的索引数据不是普通的字符串或者数值ID,而是时间/日期类型的数据。而pandas的时间序列工具则非常适合用来处理这类带时间戳的索引数据。

这里最常用的就是pandas中的DatetimeIndex时间索引数据类型。首先我们来看一个最简单的例子,创建一个Series类型的时间序列:

代码片段:

import pandas as pd

index = pd.DatetimeIndex(['2017-7-1', '2017-8-1',
                          '2018-7-1', '2018-8-1',
                          '2019-7-1', '2019-8-1'])
data = pd.Series([3, 4, 5, 6, 7, 8], index=index)
print(data)

运行结果:

2017-07-01    3
2017-08-01    4
2018-07-01    5
2018-08-01    6
2019-07-01    7
2019-08-01    8
dtype: int64

在这个例子中,我们首先是生成了一个DatetimeIndex类型的对象,顾名思义,他是一个专门的日期时间类的索引对象,然后我们再用他作为参数值,生成了一个Series序列类型的对象。

那么,这么做的好处在哪呢?也就是说pandas的便捷之处体现在哪?有很多,不着急,我们这里只结合这个例子简单说一点,即:简便的时间序列索引操作。

我们分别针对三种不同的索引方式举例进行说明:

1.查看某个具体时间点对应的值,例如:2018年8月1日的值;
2.查看两个具体时间点对应的时间区间内的取值,例如:2017年7月15日~2018年7月15日之间的取值;
3.某个指定年份中的取值,例如:2018年全年的取值。

代码片段:

import pandas as pd

index = pd.DatetimeIndex(['2017-7-1', '2017-8-1',
                          '2018-7-1', '2018-8-1',
                          '2019-7-1', '2019-8-1'])
data = pd.Series([3, 4, 5, 6, 7, 8], index=index)

print(data['2018-8-1'])
print(data['2017-7-15':'2018-7-15'])
print(data['2018'])

运行结果:

6

2017-08-01    4
2018-07-01    5
dtype: int64

2018-07-01    5
2018-08-01    6
dtype: int64

当然,将日期作为索引所带来的便利性远远不止于此,我们下面继续讲解。

初步领略了Pandas表示时间序列的便捷之后,下面我们开始系统的进行相关内容的梳理,其实最为核心的还是pandas时间序列中的核心数据结构。

2.时间戳数据类型及索引结构

这个我们在上一节的末尾提到过,pandas中提供了Timestamp类型数据来表示时间戳,他在numpy.datetime64的基础上构建,具有类似的良好性能,同时兼具有python原生的datetime类型的易用性。而时间戳数据构成的索引数据结构就是DatetimeIndex,我们在上面的例子中已经见过。

Timestamp和DatetimeIndex是最基础、也是最重要的一类数据结构,生成这两种类型数据的核心函数方法是pd.to_datetime()函数,最关键的是,这个方法也可以灵活的解析不同的日期文本格式。

对于pd.to_datetime()方法,传入一个具体的日期,返回的就是一个Timestamp类型时间戳。

代码片段:

import pandas as pd

date = pd.to_datetime('2019-5-3')
print(date)
print(type(date))

运行结果:

2019-05-03 00:00:00
<class 'pandas.tslib.Timestamp'>

如果我们传入的是一个时间序列,则会返回一个DatetimeIndex时间索引类型:

代码片段:

import pandas as pd
from datetime import datetime

dates = pd.to_datetime(['2019-5-1', '20190502',
                       '5/3/2019', datetime(2019, 5, 4)])
print(dates)
print(type(dates))

运行结果:

DatetimeIndex(['2019-05-01', '2019-05-02', '2019-05-03', '2019-05-04'], dtype='datetime64[ns]', freq=None)
<class 'pandas.tseries.index.DatetimeIndex'>

从运行结果来看,我们确实利用了一个时间序列(列表类型),生成了一个DatetimeIndex索引类的数据,并且不难发现,在我们传入的时间序列当中,每一个时间的文本形式都不同。

如果想更为简便的创建有规律的时间序列,该如何进行处理?比如我们可以指定起止日期时间和频率,然后一次性生成有规律的时间序列:

代码片段:

import pandas as pd

dates1 = pd.date_range('2018-7-1','2018-7-15')
dates2 = pd.date_range('2019/5/1','2019/5/2',freq='H')

print(dates1)
print(dates2)

运行结果:

DatetimeIndex(['2018-07-01', '2018-07-02', '2018-07-03', '2018-07-04',
               '2018-07-05', '2018-07-06', '2018-07-07', '2018-07-08',
               '2018-07-09', '2018-07-10', '2018-07-11', '2018-07-12',
               '2018-07-13', '2018-07-14', '2018-07-15'],
              dtype='datetime64[ns]', freq='D')

DatetimeIndex(['2019-05-01 00:00:00', '2019-05-01 01:00:00',
               '2019-05-01 02:00:00', '2019-05-01 03:00:00',
               '2019-05-01 04:00:00', '2019-05-01 05:00:00',
               '2019-05-01 06:00:00', '2019-05-01 07:00:00',
               '2019-05-01 08:00:00', '2019-05-01 09:00:00',
               '2019-05-01 10:00:00', '2019-05-01 11:00:00',
               '2019-05-01 12:00:00', '2019-05-01 13:00:00',
               '2019-05-01 14:00:00', '2019-05-01 15:00:00',
               '2019-05-01 16:00:00', '2019-05-01 17:00:00',
               '2019-05-01 18:00:00', '2019-05-01 19:00:00',
               '2019-05-01 20:00:00', '2019-05-01 21:00:00',
               '2019-05-01 22:00:00', '2019-05-01 23:00:00',
               '2019-05-02 00:00:00'],
              dtype='datetime64[ns]', freq='H')

从运行的结果中我们看到,第一个例子中我们没有指定频率,则频率默认为天,而第二个例子中我们指定了频率为小时,因此程序就按照我们指定的频率要求生成了相应的DatetimeIndex类型的索引数据。

当然,我们不仅仅限制在指定起止时间,还有另外一种方法,那就是指定起始时间和周期,这也对应了一类应用场景:

代码片段:

import pandas as pd

dates1 = pd.date_range('2018-7-1',periods=5)
dates2 = pd.date_range('2019/5/1',periods=8,freq='H')

print(dates1)
print(dates2)

运行结果:
```
DatetimeIndex(['2018-07-01', '2018-07-02', '2018-07-03', '2018-07-04',
'2018-07-05'],

top Created with Sketch.