1. Pandas简介
Pandas是基于NumPy编写的数据处理库,是Python语言下常用的数据科学工具,可用于数据挖掘、数据分析、数据清洗等工作。它的主要数据结构是Series(一维数据)和DataFrame(二维数据),能灵活处理多种数据类型,包括时间序列、实时数据、关系型数据等。Pandas的API接口简洁,易于使用。
2. 重采样(resample())
Pandas的resample()方法是对时间序列进行重采样的方法,根据需要将时间序列的数据转化为规则的时间序列或者按照某个规则对时间序列进行分组。
2.1 重采样的基本语法
可以先构造一个简单的时间序列:
import pandas as pd
import numpy as np
# 构造一个日期列索引为2017年1月1日至2017年1月5日,数据为从1开始的5个数字的时间序列
dates = pd.date_range('1/1/2017', periods=5, freq='D')
ts = pd.Series(np.arange(1, 6), index=dates)
print(ts)
打印结果:
2017-01-01 1
2017-01-02 2
2017-01-03 3
2017-01-04 4
2017-01-05 5
dtype: int32
通过上述代码可以实现对时间序列的构造。
进行重采样的方法如下:
# 将时间序列转化为每周数据,这里的W可以指定其他的时间,如W-MON表示周一,W-TUE表示周二
print(ts.resample('W').sum())
结果如下:
2017-01-01 1
2017-01-08 14
Freq: W-SUN, dtype: int32
从上述结果可以看出,resample函数的参数'W'表示将时间序列的频率由天变为周,而'sum()'函数则表示对每周的数据求和。
2.2 重采样的方法
resample函数除了使用'W'作为参数外,还可以使用其他的参数:
参数 | 说明 |
---|---|
'D' | 按日重采样 |
'W' | 按周重采样 |
'M' | 按月重采样 |
'Q' | 按季度重采样 |
'A' | 按年重采样 |
'H' | 按小时重采样 |
'T' | 按分钟重采样 |
比如,我们可以将时间序列的频率由天变为小时,代码如下:
# 将时间序列转化为每小时数据,参数'H'表示每小时,函数mean()表示对每小时的数据进行求平均值
print(ts.resample('H').mean())
结果如下:
2017-01-01 00:00:00 1.0
2017-01-01 01:00:00 NaN
2017-01-01 02:00:00 NaN
2017-01-01 03:00:00 NaN
2017-01-01 04:00:00 NaN
...
2017-01-04 20:00:00 NaN
2017-01-04 21:00:00 NaN
2017-01-04 22:00:00 NaN
2017-01-04 23:00:00 NaN
2017-01-05 00:00:00 5.0
Freq: H, Length: 97, dtype: float64
3. 频度转换(asfreq())
asfreq()方法主要是对不规则时间序列进行频度转换,将时间索引中的时间点转换为另外一个频度下的时间点。也可以认为是对时间序列的重新索引,所以结果包含了原始时间序列的数据。
3.1 频度转换的基本语法
同样可以先构造一个简单的时间序列:
# 构造一个日期列索引为2017年1月1日至2017年1月5日,数据为从1开始的5个数字的时间序列
dates = pd.date_range('1/1/2017', periods=5, freq='D')
ts = pd.Series(np.arange(1, 6), index=dates)
print(ts)
结果如下:
2017-01-01 1
2017-01-02 2
2017-01-03 3
2017-01-04 4
2017-01-05 5
dtype: int32
进行频度转换的方法如下:
# 将时间序列的频率从天变为小时,返回转换后的新序列,缺失的值用NaN填充
print(ts.asfreq('H'))
结果如下:
2017-01-01 00:00:00 1.0
2017-01-01 01:00:00 NaN
2017-01-01 02:00:00 NaN
2017-01-01 03:00:00 NaN
2017-01-01 04:00:00 NaN
...
2017-01-04 20:00:00 NaN
2017-01-04 21:00:00 NaN
2017-01-04 22:00:00 NaN
2017-01-04 23:00:00 NaN
2017-01-05 00:00:00 5.0
Freq: H, Length: 97, dtype: float64
从结果可以看出,频度转换结果包含了原始时间序列的所有数据,当时间序列的某个时间点不存在时,使用NaN来填充。
3.2 频度转换的方法
asfreq()方法的参数可以是和resample()一样的字符串标识符。
除了转换频度外,asfreq()还有一个可选的参数“method”(插值法),可以使用前向填充或者后向填充的方式让生成的新序列中缺失的值被填充上数据。
使用前向填充的方式处理缺失值的代码如下:
# 将时间序列的频率从天变为小时,返回转换后的新序列,缺失的值用前面的值填充(f),不会出现NaN了
print(ts.asfreq('H', method='ffill'))
结果如下:
2017-01-01 00:00:00 1
2017-01-01 01:00:00 1
2017-01-01 02:00:00 1
2017-01-01 03:00:00 1
2017-01-01 04:00:00 1
...
2017-01-04 20:00:00 4
2017-01-04 21:00:00 4
2017-01-04 22:00:00 4
2017-01-04 23:00:00 4
2017-01-05 00:00:00 5
Freq: H, dtype: int32
从结果中可以看出,缺失值已经被前向填充了,而所有缺失值的位置都被上一个数据填充了,不会有NaN了。
3.3 时间序列重采样和频度转换的区别
重采样和频度转换其实非常类似,都是对时间序列进行了转化。不过它们存在两个主要的区别:
重采样本质上是通过重新划分时间间隔来执行groupby()聚合操作,生成的结果是聚合之后的新视图或一组视图。这意味着它们返回与原始时间序列不同的数据。
频度转换在返回聚合之前是重新示例化索引,这意味着它们将返回与原始时间序列相同的数据(如果没有插值)。
也就是说,重采样返回的是原始数据的聚合结果,而频度转换直接对原始数据进行重新采样,并且插值后返回。所以,它们在数据处理的方式上有很大的区别。
总结
重采样(resample())和频度转换(asfreq())都是对时间序列进行重构的方法。重采样是对时间序列的数据进行分组聚合,生成新的时间序列。频度转换是对时间序列的时间索引进行重新示例化,用于将时间序列转换到一个不同的时间频度下。
两者相比较,重采样的结果是对原始时间序列数据的聚合,而频度转换的结果是对原始数据的重新采样和插值。在实践中,根据数据分析的需求来选择重采样或频度转换。