数据分析经常会遇到带有时间序列的数据,接下来我们看一下,利用pandas如何处理这类数据。
时间序列
- 时间戳(timestamp)
- 固定周期(period)
- 时间间隔(interval)
![](https://img.haomeiwen.com/i17333643/e0a1142fad62d420.png)
一、创建时间序列
1、date_range
- 可以指定开始时间与周期
- H:小时
- D:天
- M:月
以天(day)为单位,输出后10天的时间序列
#TIMES #2016 Jul 1 7/1/2016 1/7/2016 2016-07-01 2016/07/01
#时间格式可以换成上面的
rng = pd.date_range('2016/07/01',periods=10,freq='D')
rng
![](https://img.haomeiwen.com/i17333643/5e96918cb51c1616.png)
也可以3天为单位,输出后10个序列
rng = pd.date_range('2016/07/01',periods=10,freq='3D')
rng
![](https://img.haomeiwen.com/i17333643/15a1cce7a306b86b.png)
或者指定起始时间
rng = pd.date_range(start = '2016/07/01',end = '2016/07/10',freq='D')
rng
![](https://img.haomeiwen.com/i17333643/068783c72812eb3e.png)
生成Series序列
time = pd.Series(np.random.randn(20),index=pd.date_range(dt.datetime(2016,1,1),periods=20))
time
![](https://img.haomeiwen.com/i17333643/ec18ecaf3ece9180.png)
2、truncate过滤
time.truncate(before='2016-1-10')#过滤掉2016-1-10之前的数据
![](https://img.haomeiwen.com/i17333643/01c5b0ac3178415a.png)
time.truncate(after='2016-1-10')#过滤掉之后的
![](https://img.haomeiwen.com/i17333643/2b0487b59c7a0292.png)
提取数据
print(time['2016-01-15'])
![](https://img.haomeiwen.com/i17333643/239ac0b7195cf264.png)
print(time['2016-01-15':'2016-01-20'])#切片的方式
![](https://img.haomeiwen.com/i17333643/a18d624b9692611c.png)
data = pd.date_range('2010-01-01','2011-01-01',freq='M')
data
![](https://img.haomeiwen.com/i17333643/19a0a6e5dc1b718c.png)
参数freq中可以选的数值:
![](https://img.haomeiwen.com/i17333643/8b75bd11907e9517.png)
3、时间戳
pd.Timestamp('2016-07-10')
![](https://img.haomeiwen.com/i17333643/51d09e0861013e65.png)
#可以指定更多细节
pd.Timestamp('2016-07-10 10')
![](https://img.haomeiwen.com/i17333643/41ae52fc330e6887.png)
pd.Timestamp('2016-07-10 10:15')
![](https://img.haomeiwen.com/i17333643/5053375e20578c5b.png)
4、时间区间
pd.Period('2016-01')
![](https://img.haomeiwen.com/i17333643/1ee97ca5f50d96cd.png)
pd.Period('2016-01-01')
![](https://img.haomeiwen.com/i17333643/addff7b374a61166.png)
5、时间加减
- TIME OFFSETS
产生一个一天的时间偏移量
#产生一个一天的时间偏移量
pd.Timedelta('1 day')
![](https://img.haomeiwen.com/i17333643/031db30a84b43e09.png)
#得到2016-01-01 10:10的后一天时刻:
pd.Period('2016-01-01 10:10') + pd.Timedelta('1 day')
![](https://img.haomeiwen.com/i17333643/cf06ef3c3e484b9a.png)
#时间戳加减:
pd.Timestamp('2016-01-01 10:10') + pd.Timedelta('1 day')
![](https://img.haomeiwen.com/i17333643/c7588ff1b74500df.png)
#加15ns
pd.Timestamp('2016-01-01 10:10') + pd.Timedelta('15 ns')
![](https://img.haomeiwen.com/i17333643/f8d9e0903556a88a.png)
在时间间隔freq参数中,我们既可以写成25H,也可以写成1D1H这种通俗的表达:
pd.period_range('2016-01-01 10:10',freq='25H',periods=10)
![](https://img.haomeiwen.com/i17333643/64d536a045deeefc.png)
pd.period_range('2016-01-01 10:10',freq='1D1H',periods=10)
![](https://img.haomeiwen.com/i17333643/0cb7dc4778ce5e9c.png)
6、指定索引
rng = pd.date_range('2016 Jul 1',periods=10,freq='D')
pd.Series(range(len(rng)),index=rng)
![](https://img.haomeiwen.com/i17333643/462a32ddca7ad557.png)
#构造任意的Series结构时间序列数据:
periods=[pd.Period('2016-01'),pd.Period('2016-02'),pd.Period('2016-03')]
ts = pd.Series(np.random.randn(len(periods)),index=periods)
ts
![](https://img.haomeiwen.com/i17333643/cfa6c558fb14d301.png)
type(ts.index)
![](https://img.haomeiwen.com/i17333643/d28ad73b6caa822a.png)
7、时间戳和时间周期可以转换
#产生时间周期
ts = pd.Series(range(10),pd.date_range('07-10-16 8:00',periods=10,freq='H'))
ts
![](https://img.haomeiwen.com/i17333643/59322db3fab064d3.png)
#将时间周期转化为时间戳
ts_period = ts.to_period()
ts_period
![](https://img.haomeiwen.com/i17333643/27fd66d17c1aa629.png)
8、时间周期和时间戳的区别
- 对时间周期的切片操作
ts_period['2016-07-10 08:30':'2016-07-10 11:45']
![](https://img.haomeiwen.com/i17333643/3c411c1a18058f8a.png)
- 对时间戳的切片操作
ts['2016-07-10 08:30':'2016-07-10 11:45']
![](https://img.haomeiwen.com/i17333643/30709a571088b915.png)
二、数据重采样
- 时间数据由一个频率转换到另一个频率
- 降采样:例如将365天数据变为12个月的数据
- 升采样:相反
#从1/1/2011开始,时间间隔为1天,产生90个时间数据
rng = pd.date_range('1/1/2011',periods=90,freq='D')
ts = pd.Series(np.random.randn(len(rng)),index=rng)
ts.head()
![](https://img.haomeiwen.com/i17333643/343e8e4dfb61f46a.png)
1、降采样
#将以上数据降采样为月数据,观察每个月数据之和、
ts.resample('M').sum()
![](https://img.haomeiwen.com/i17333643/db822e3191c1cc70.png)
#降采样为3天,并求和
ts.resample('3D').sum()
![](https://img.haomeiwen.com/i17333643/1b16ba667d5ed857.png)
计算降采样后数据均值
#计算降采样后数据均值
day3Ts=ts.resample('3D').mean()
day3Ts
![](https://img.haomeiwen.com/i17333643/b0428ced79ba8a85.png)
2、升采样
直接升采样是有问题的,因为有数据缺失
#
day3Ts.resample('D').asfreq()
![](https://img.haomeiwen.com/i17333643/e2585d567d2a19f1.png)
使用插值的方法
- ffill 空值取前面的值
- bfill 空值取后面的值
- interpolate 线性取值
day3Ts.resample('D').ffill(1)#一个值填充
![](https://img.haomeiwen.com/i17333643/4a9281ded07eb1be.png)
day3Ts.resample('D').ffill(2)#两个值填充
![](https://img.haomeiwen.com/i17333643/4475557f9a5f174f.png)
全部空值填充
day3Ts.resample('D').ffill()
![](https://img.haomeiwen.com/i17333643/417895c711ed561b.png)
day3Ts.resample('D').bfill(1)
![](https://img.haomeiwen.com/i17333643/58238840d2f1f7b6.png)
day3Ts.resample('D').bfill(2)
![](https://img.haomeiwen.com/i17333643/1d13db6d8a6174dc.png)
day3Ts.resample('D').bfill()
![](https://img.haomeiwen.com/i17333643/f8d6b6f5d65573a9.png)
使用interpolate线性取值
# 使用interpolate线性取值
day3Ts.resample('D').interpolate('linear')
![](https://img.haomeiwen.com/i17333643/56217768d14f586b.png)
三、Pandas滑动窗口
为了提升数据的准确性,将某个点的取值扩大到包含这个点的一段区间,用区间来进行判断,这个区间就是窗口。例如想使用2011年1月1日的一个数据,单取这个时间点的数据当然是可行的,但是太过绝对,有没有更好的办法呢?可以选取2010年12月16日到2011年1月15日,通过求均值来评估1月1日这个点的值,2010-12-16到2011-1-15就是一个窗口,窗口的长度window=30.
移动窗口就是窗口向一端滑行,默认是从右往左,每次滑行并不是区间整块的滑行,而是一个单位一个单位的滑行。例如窗口2010-12-16到2011-1-15,下一个窗口并不是2011-1-15到2011-2-15,而是2010-12-17到2011-1-16(假设数据的截取是以天为单位),整体向右移动一个单位,而不是一个窗口。这样统计的每个值始终都是30单位的均值。
也就是我们在统计学中的移动平均法。
import matplotlib.pylab
import numpy as np
import pandas as pd
%matplotlib inline
df = pd.Series(np.random.randn(600),index=pd.date_range('7/1/2016',freq='D',periods=600))
df.head()
![](https://img.haomeiwen.com/i17333643/1787c326af3d9b4b.png)
#指定该序列一个单位长度为10的滑块
r=df.rolling(window = 10)
r
![](https://img.haomeiwen.com/i17333643/ecfbcf6030ad1b97.png)
#输出滑块内的平均值,窗口中的值从覆盖整个窗口的位置开始产生,在此之前即为NaN,举例如下:窗口大小为10,前9个都不足够为一个一个窗口的长度,因此都无法取值。
r.mean()
![](https://img.haomeiwen.com/i17333643/be984f3637cc6158.png)
# 通过画图库来看原始序列与滑动窗口产生序列的关系图,原始数据用红色表示,移动平均后数据用蓝色点表示:
import matplotlib.pyplot as plt
plt.figure(figsize=(15,5))
df.plot(style='r--')
df.rolling(window=10).mean().plot(style='b')#可以看到,原始值浮动差异较大,而移动平均后数值较为平稳。
![](https://img.haomeiwen.com/i17333643/3b18e52ce46b3533.png)
网友评论