python+pandas生成指定日期和重采样的方法
python日期的范围、频率、重采样以及频率转换
pandas有一整套的标准时间序列频率以及用于重采样、频率推断、生成固定频率日期范围的工具。
生成指定日期范围的范围
pandas.date_range()用于生成指定长度的DatatimeIndex:
1)默认情况下,date_range会按着时间间隔为天的方式生成从给定开始到结束时间的时间戳数组;
2)如果只指定开始或结束时间,还需要periods标定时间长度。
importpandasaspd pd.date_range('2017-6-20','2017-6-27')
DatetimeIndex(['2017-06-20','2017-06-21','2017-06-22','2017-06-23', '2017-06-24','2017-06-25','2017-06-26','2017-06-27'], dtype='datetime64[ns]',freq='D')
pd.date_range('2017-6-2012:59:30','2017-6-27')
DatetimeIndex(['2017-06-2012:59:30','2017-06-2112:59:30', '2017-06-2212:59:30','2017-06-2312:59:30', '2017-06-2412:59:30','2017-06-2512:59:30', '2017-06-2612:59:30'], dtype='datetime64[ns]',freq='D')
pd.date_range('2017-6-2012:59:30',periods=8)
DatetimeIndex(['2017-06-2012:59:30','2017-06-2112:59:30', '2017-06-2212:59:30','2017-06-2312:59:30', '2017-06-2412:59:30','2017-06-2512:59:30', '2017-06-2612:59:30','2017-06-2712:59:30'], dtype='datetime64[ns]',freq='D')
pd.date_range('2017-6-2012:59:30',periods=8,normalize=True)
DatetimeIndex(['2017-06-20','2017-06-21','2017-06-22','2017-06-23', '2017-06-24','2017-06-25','2017-06-26','2017-06-27'], dtype='datetime64[ns]',freq='D')
频率和日期偏移量
pandas中的频率是由一个基础频率(M、H)也可以是(Hour、Minute、h、min等)
pd.date_range('2017-6-27',periods=7,freq='1h30min')
DatetimeIndex(['2017-06-2700:00:00','2017-06-2701:30:00', '2017-06-2703:00:00','2017-06-2704:30:00', '2017-06-2706:00:00','2017-06-2707:30:00', '2017-06-2709:00:00'], dtype='datetime64[ns]',freq='90T')
pd.date_range('2017-6-27',periods=7,freq='M')
DatetimeIndex(['2017-06-30','2017-07-31','2017-08-31','2017-09-30', '2017-10-31','2017-11-30','2017-12-31'], dtype='datetime64[ns]',freq='M')
pd.date_range('2017-6-27',periods=7,freq='d')
DatetimeIndex(['2017-06-27','2017-06-28','2017-06-29','2017-06-30', '2017-07-01','2017-07-02','2017-07-03'], dtype='datetime64[ns]',freq='D')
pd.date_range('2017-6-27',periods=7,freq='H')
DatetimeIndex(['2017-06-2700:00:00','2017-06-2701:00:00', '2017-06-2702:00:00','2017-06-2703:00:00', '2017-06-2704:00:00','2017-06-2705:00:00', '2017-06-2706:00:00'], dtype='datetime64[ns]',freq='H')
常用的基础频率
别名 | 偏移量 | 说明 |
---|---|---|
D/d | Day | 每日历日 |
B | BusinessDay | 每工作日 |
H/h | Hour | 每小时 |
T或min | Minute | 每分 |
S | Secend | 每秒 |
L或ms | Milli | 每毫秒(每千分之一秒) |
U | Micro | 每微秒(即百万分之一秒) |
M | MonthEnd | 每月最后一个日历日 |
BM | BusinessDayEnd | 每月最后一个工作 |
上表只展示了部分!
WOM日期(可获得例如“每月第3个星期五”)
pd.date_range('2017-06-01','2017-07-31',freq='WOM-3FRI')
DatetimeIndex(['2017-06-16','2017-07-21'],dtype='datetime64[ns]',freq='WOM-3FRI')
重采样及频率转换
降采样:高频数据到低频数据
升采样:低频数据到高频数据
主要函数:resample()(pandas对象都会有这个方法)
resample方法的参数
参数 | 说明 |
---|---|
freq | 表示重采样频率,例如‘M'、‘5min',Second(15) |
how='mean' | 用于产生聚合值的函数名或数组函数,例如‘mean'、‘ohlc'、np.max等,默认是‘mean',其他常用的值由:‘first'、‘last'、‘median'、‘max'、‘min' |
axis=0 | 默认是纵轴,横轴设置axis=1 |
fill_method=None | 升采样时如何插值,比如‘ffill'、‘bfill'等 |
closed=‘right' | 在降采样时,各时间段的哪一段是闭合的,‘right'或‘left',默认‘right' |
label=‘right' | 在降采样时,如何设置聚合值的标签,例如,9:30-9:35会被标记成9:30还是9:35,默认9:35 |
loffset=None | 面元标签的时间校正值,比如‘-1s'或Second(-1)用于将聚合标签调早1秒 |
limit=None | 在向前或向后填充时,允许填充的最大时期数 |
kind=None | 聚合到时期(‘period')或时间戳(‘timestamp'),默认聚合到时间序列的索引类型 |
convention=None | 当重采样时期时,将低频率转换到高频率所采用的约定(start或end)。默认‘end' |
降采样
需考虑:
1)各区间哪边是闭合的(参数:closed)
2)如何标记各聚合面元,用区间的开头还是末尾(参数:label)
ts_index=pd.date_range('2017-06-20',periods=12,freq='1min')#一分钟采样数据 ts=pd.Series(np.arange(12),index=ts_index)
ts
2017-06-2000:00:000 2017-06-2000:01:001 2017-06-2000:02:002 2017-06-2000:03:003 2017-06-2000:04:004 2017-06-2000:05:005 2017-06-2000:06:006 2017-06-2000:07:007 2017-06-2000:08:008 2017-06-2000:09:009 2017-06-2000:10:0010 2017-06-2000:11:0011 Freq:T,dtype:int32
聚合到5分钟
ts.resample('5min',how='sum')
C:\ProgramFiles\anaconda\lib\site-packages\ipykernel\__main__.py:1:FutureWarning:howin.resample()isdeprecated thenewsyntaxis.resample(...).sum() if__name__=='__main__': 2017-06-2000:00:0010 2017-06-2000:05:0035 2017-06-2000:10:0021 Freq:5T,dtype:int32
ts.resample('5min',how='sum',closed='left')
C:\ProgramFiles\anaconda\lib\site-packages\ipykernel\__main__.py:1:FutureWarning:howin.resample()isdeprecated thenewsyntaxis.resample(...).sum() if__name__=='__main__': 2017-06-2000:00:0010 2017-06-2000:05:0035 2017-06-2000:10:0021 Freq:5T,dtype:int32
ts.resample('5min',how='sum',closed='left',label='left')
C:\ProgramFiles\anaconda\lib\site-packages\ipykernel\__main__.py:1:FutureWarning:howin.resample()isdeprecated thenewsyntaxis.resample(...).sum() if__name__=='__main__': 2017-06-2000:00:0010 2017-06-2000:05:0035 2017-06-2000:10:0021 Freq:5T,dtype:int32
通过groupby进行重插样
另外一种降采样方法
ts1_index=pd.date_range('2017-6-01',periods=100,freq='d') ts1=pd.Series(np.arange(100),index=ts1_index) ts1.head()
2017-06-010 2017-06-021 2017-06-032 2017-06-043 2017-06-054 Freq:D,dtype:int32
ts1.groupby(lambdax:x.month).mean()
614.5 745.0 876.0 995.5 dtype:float64
ts1.groupby(lambdax:x.weekday).mean()
049.5 150.5 251.5 349.0 450.0 547.5 648.5 dtype:float64
df1=pd.DataFrame(np.arange(200).reshape(100,2),index=ts1_index)
df1.groupby(lambdax:x.weekday).mean()
0
1
0
99
100
1
101
102
2
103
104
3
98
99
4
100
101
5
95
96
6
97
98
对于具有时间序列索引的pandas数据结构,当groupby传入一个函数时,可以对时间索引对应列进行聚合
升采样
升采样没有聚合,但是需要填充
df2=pd.DataFrame(np.arange(200).reshape(100,2),index=ts1_index,columns=['add1','add2']) df2.head()
add1
add2
2017-06-01
0
1
2017-06-02
2
3
2017-06-03
4
5
2017-06-04
6
7
2017-06-05
8
9
df2.resample('W-THU',fill_method='ffill')
C:\ProgramFiles\anaconda\lib\site-packages\ipykernel\__main__.py:1:FutureWarning:fill_methodisdeprecatedto.resample() thenewsyntaxis.resample(...).ffill() if__name__=='__main__':
add1
add2
2017-06-01
0
1
2017-06-08
14
15
2017-06-15
28
29
2017-06-22
42
43
2017-06-29
56
57
2017-07-06
70
71
2017-07-13
84
85
2017-07-20
98
99
2017-07-27
112
113
2017-08-03
126
127
2017-08-10
140
141
2017-08-17
154
155
2017-08-24
168
169
2017-08-31
182
183
2017-09-07
196
197
2017-09-14
198
199
总结
本篇博客主要内容:
1)生成指定时间段,指定频率的日期
2)对含有时间索引的pandas数据进行重采样,包括降采样和升采样等。