时间序列是指在一定时间内按时间顺序测量的某个变量的取值序列,不管在什么行业,时间序列都是一种非常重要的数据形式,很多统计数据以及数据的规律也都和时间序列有着非常重要的联系。常见的时间序列数据有一天内随着时间变化的温度序列,又或者交易时间内不断波动的股票价格序列。Pandas的时间序列处理能力是非常强大的。

Panda的时间序列处理中最常见的数据类型为datetime,那么什么是datetime呢。顾名思义就是既有date也有time。一般我们表示一个时间,如2021-6-6 14:00:00就是一个datetime。2021-6-6是date 14:00:00就是time。而pandas中使用数据类型timedelta表示两个datetime之间的时间差。

 

时间序列的创建与转换

pd.date_range(start=None, end=None, periods=None, freq='D')

start和end以及freq配合能够生成start和end范围内以频率freq的一组时间索引

start和periods以及freq配合能够生成从start开始的频率为freq的periods个时间索引。

关于freq参数的选择:

别名

偏移量类型

说明

D

Day

每日历日

B

BusinessDay

每工作日

H

Hour

每小时

T/min

Minute

每分

S

Second

每秒

L/ms

Million

每毫秒

U

Micro

每微秒

M

MonthEnd

每月最后一个日历日

BM

BusinessMonthEnd

每月最后一个工作日

MS

MonthBegin

每月第一个日历日

BMS

BusinessMonthBegin

每月第一个工作日

需要注意的是,可以在别名前加数字表示乘,比如“10D”就表示十天。

pd.date_range(start="20170812", end="20190812",freq="M")

结果:
DatetimeIndex(['2017-08-31', '2017-09-30', '2017-10-31', '2017-11-30',
               '2017-12-31', '2018-01-31', '2018-02-28', '2018-03-31',
               '2018-04-30', '2018-05-31', '2018-06-30', '2018-07-31',
               '2018-08-31', '2018-09-30', '2018-10-31', '2018-11-30',
               '2018-12-31', '2019-01-31', '2019-02-28', '2019-03-31',
               '2019-04-30', '2019-05-31', '2019-06-30', '2019-07-31'],
              dtype='datetime64[ns]', freq='M')


index=pd.date_range(start="20170812", periods=24,freq="10D")
index

结果:
DatetimeIndex(['2017-08-12', '2017-08-22', '2017-09-01', '2017-09-11',
               '2017-09-21', '2017-10-01', '2017-10-11', '2017-10-21',
               '2017-10-31', '2017-11-10', '2017-11-20', '2017-11-30',
               '2017-12-10', '2017-12-20', '2017-12-30', '2018-01-09',
               '2018-01-19', '2018-01-29', '2018-02-08', '2018-02-18',
               '2018-02-28', '2018-03-10', '2018-03-20', '2018-03-30'],
              dtype='datetime64[ns]', freq='10D')

 

对于很多时候我们从csv文件中导入的数据是字符串格式的时间,如'2017-08-31'那我们如何把字符串转换成datetime格式呢。pandas提供to_datetime()来完成这个功能。

pandas.to_datetime(arg,errors ='raise',utc = None,format = None,unit = None )

参数

含义

errors

三种取值,‘ignore’, ‘raise’, ‘coerce’,默认为raise。

'raise',则无效的解析将引发异常

'coerce',那么无效解析将被设置为NaT

'ignore',那么无效的解析将返回输入值

utc

布尔值,默认为none。返回utc即协调世界时。

format

格式化显示时间的格式。

unit

默认值为‘ns’,则将会精确到微妙,‘s'为秒。

关于format的格式化参数,大部分情况下可以不用写,但是对于pandas无法格式化的时间字符串,我们可以使用该参数:

格式代码

含义

%Y

4位数的年

%y

2位数的年

%m

2位数的月[01,12]

%d

2位数的日[01,31]

%H

时(24小时制)[00,23]

%l

时(12小时制)[01,12]

%M

2位数的分[00,59]

%S

秒[00,61](有闰秒的存在)

%w

用整数表示的星期几[0(星期天),6]

%F

%Y-%m-%d简写形式例如,2017-06-27

%D

%m/%d/%y简写形式

比如21.6.6 就是"%y.%m.%d" , 14:16:00 2021-6-6 就"%H:%M:%S %Y-%m-%d”。

 

而转换时间序列的时候,也有一些数据时间分布在不同的列中,如一列是year,一列是month,一列是day。我们固然可以讲数据先处理合成为一列,pandas针对此情况也提供PeriodIndex函数。使用时类似于date_range,如:

pd.PeriodIndex(year=data["year"],month=data["month"],day=data["day"],hour=data["hour"],freq="H")

提取时间序列的属性

pandas提供.dt接口来实现提取时间序列的属性这个功能。对于一个datetime数据,仅需调用.dt即可。

如下面演示2019-01-02的信息:

# 一年中的第几天
In [13]: data.trade_date.dt.dayofweek[0]
Out[13]: 2

# 返回对应日期
In [14]: data.trade_date.dt.date[0]
Out[14]: datetime.date(2019, 1, 2)

# 返回周数
In [15]: data.trade_date.dt.weekofyear[0]
Out[15]: 1

# 返回周几
In [16]: data.trade_date.dt.weekday_name[0]
Out[16]: 'Wednesday'

重采样

重采样:指的是将时间序列从一个频率转化为另一个频率进行处理的过程,将高频率数据转化为低频率数据为降采样,低频率转化为高频率为升采样 pandas提供了一个resample的方法来帮助我们实现频率转化。

其实resample就是基于时间的groupby操作,根据采样是从低频到高频还是从高频到低频可以分为升采样和降采样两种方式。

降采样:是从高频到低频的聚合操作,resample 后第一个参数为频率参数,默认用索引进行groupby。所以之前使用pd.date_range生成的时间索引或者todatetime生成的datetime进行setindex后可以直接设置为索引来降采样,如果不是时间索引。则可以使用参数on制定时间列。在后面使用.count() .mean等统计函数执行同级操作。例如

data.resample('Q',on='trade_date')["close"].mean()

升采样:当采样的频率低于原有的频率时,即为升采样。升采样是对原有的时间粒度更为细粒度的划分,所以升采样时会产生缺失值。对resample后的结果应用.asfreq()会返回新频率下的结果。如果想要填充缺失值可以采用向后填充.bfill()或向前填充.ffill()的方式。