文章目录
时期(period)表示的是时间区间,比如数日、数月、数季、数年等。period
类表示的就是这种数据类型,其构造函数需要一个字符串或整数,以及下表的频率。
# 表示从2007年1月1日-2007年12月31日之间的整段时间
p=pd.Period(2007,freq='A-DEC') # Period('2007', 'A-DEC')
p+5 # Period('2012', 'A-DEC')
p-2 # Period('2005', 'A-DEC')
pd.Period(2014,freq='A-DEC')-p # <7 * YearEnds: month=12>
period_range
函数:用于创建规则的时期范围。
rng=pd.period_range('1/1/2000','6/30/2000',freq='M')
# PeriodIndex(['2000-01', '2000-02', '2000-03', '2000-04', '2000-05', '2000-06'], dtype='period[M]', freq='M')
pd.Series(np.random.randn(len(rng)),index=rng)
# 2000-01 -0.079781
# 2000-02 -0.479156
# 2000-03 -1.101500
# 2000-04 0.123803
# 2000-05 1.200151
# 2000-06 -0.034314
# Freq: M, dtype: float64
values=['2001Q3','2002Q2','2003Q3']
index=pd.PeriodIndex(values,freq='Q-DEC')
# PeriodIndex(['2001Q3', '2002Q2', '2003Q3'], dtype='period[Q-DEC]', freq='Q-DEC')
1 时期的频率转换
Period和PeriodIndex对象都可以通过其asfreq方法转换成别的频率。假设我们有一个年度时间,希望将其转换为当年年初或年末的一个月度时期:
p=pd.Period(2007,freq='A-DEC') # Period('2007', 'A-DEC')
p.asfreq('M',how='start') # Period('2007-01', 'M')
p.asfreq('M',how='end') # Period('2007-12', 'M')
对于一个不以12月结束的财政年度,月度子时期的归属情况就不同:
p=pd.Period(2007,freq='A-JUN') # Period('2007', 'A-JUN')
p.asfreq('M',how='start') # Period('2006-07', 'M')
p.asfreq('M',how='end') # Period('2007-06', 'M')
在将高频率转换为低频率时,超时期(superperiod)是由子时期(subperiod)所属的位置决定的。例如在A-JUN频率中,2007.8实际上是属于2008年的:
p=pd.Period('2007-08',freq='M') # Period('2007-08', 'M')
p.asfreq('A-JUN') # Period('2008', 'A-JUN')
2 按季度计算的时期频率
pandas支持12种可能的季度型频率,即Q-JAN到Q-DEC:
p=pd.Period('2012Q4',freq='Q-JAN') # Period('2012Q4', 'Q-JAN')
p.asfreq('D','start') # Period('2011-11-01', 'D')
p.asfreq('D','end') # Period('2012-01-31', 'D')
要取该季度倒数第二个工作日下午4点的时间戳:
p4pm=(p.asfreq('B','end')-1).asfreq('T','start')+16*60
# Period('2012-01-30 16:00', 'T')
p4pm.to_timestamp()
# Timestamp('2012-01-30 16:00:00')
period_range
还可以用于生成季度型范围:
rng=pd.period_range('2011Q3','2012Q4',freq='Q-JAN')
# PeriodIndex(['2011Q3', '2011Q4', '2012Q1', '2012Q2', '2012Q3', '2012Q4'], dtype='period[Q-JAN]', freq='Q-JAN')
ts=pd.Series(np.arange(len(rng)),index=rng)
2011Q3 0
2011Q4 1
2012Q1 2
2012Q2 3
2012Q3 4
2012Q4 5
Freq: Q-JAN, dtype: int32
new_rng=(rng.asfreq('B','end')-1).asfreq('T','start')+16*60
ts.index=new_rng.to_timestamp()
2010-10-28 16:00:00 0
2011-01-28 16:00:00 1
2011-04-28 16:00:00 2
2011-07-28 16:00:00 3
2011-10-28 16:00:00 4
2012-01-30 16:00:00 5
dtype: int32
3 将Timestamp转换为Period(及其反向过程)
to_period
函数:将由时间戳索引的Series和DataFrame转换为以时期索引。
rng=pd.date_range('1/1/2000',periods=3,freq='M')
ts=pd.Series(np.random.randn(3),index=rng)
pts=ts.to_period()
ts
# 2000-01-31 -0.444083
# 2000-02-29 -0.359608
# 2000-03-31 -0.291763
# Freq: M, dtype: float64
pts
# 2000-01 -0.337194
# 2000-02 -0.762702
# 2000-03 0.048043
# Freq: M, dtype: float64
反向过程,使用to_timestamp即可:
pts.to_timestamp()
# 2000-01-01 -0.337194
# 2000-02-01 -0.762702
# 2000-03-01 0.048043
# Freq: MS, dtype: float64
4 通过数组创建PeriodIndex
5 重采样及频率转换
重采样(resampling):将时间序列从一个频率转换到另一个频率的处理过程。
- 降采样(downsampling):将高频率数据聚合到低频率
- 升采样(upsampling):将低频率数据转换到高频率
并不是所有的重采样都能这样划分,如将W-WED每周三转换为W-FRI每周五既不是降采样也不是升采样。
python中用resample
方法。
升采样
rng=pd.date_range('1/1/2000',periods=100,freq='D')
ts=pd.Series(np.random.randn(len(rng)),index=rng)
ts
2000-01-01 -0.840712
2000-01-02 1.231662
2000-01-03 -1.344757
2000-01-04 -0.666533
2000-01-05 1.496371
...
2000-04-05 -1.033111
2000-04-06 -1.406581
2000-04-07 1.001693
2000-04-08 1.336864
2000-04-09 -2.495294
Freq: D, Length: 100, dtype: float64
# 升采样
ts.resample('M',how='mean')
2000-01-31 -0.308841
2000-02-29 -0.068053
2000-03-31 -0.157603
2000-04-30 -0.748700
Freq: M, dtype: float64
# 升采样
ts.resample('M',how='mean',kind='period')
2000-01 -0.308841
2000-02 -0.068053
2000-03 -0.157603
2000-04 -0.748700
Freq: M, dtype: float64
降采样
rng=pd.date_range('1/1/2000',periods=12,freq='T')
ts=pd.Series(np.arange(len(rng)),index=rng)
ts
2000-01-01 00:00:00 0
2000-01-01 00:01:00 1
2000-01-01 00:02:00 2
2000-01-01 00:03:00 3
2000-01-01 00:04:00 4
2000-01-01 00:05:00 5
2000-01-01 00:06:00 6
2000-01-01 00:07:00 7
2000-01-01 00:08:00 8
2000-01-01 00:09:00 9
2000-01-01 00:10:00 10
2000-01-01 00:11:00 11
Freq: T, dtype: int32
# 降采样
# 想通过求和的方式,将数据聚合到5min块中
ts.resample('5min',how='sum')
2000-01-01 00:00:00 10
2000-01-01 00:05:00 35
2000-01-01 00:10:00 21
Freq: 5T, dtype: int32
传入的频率以“5分钟”的增量定义面元边界。默认情况下,区间左闭右开即closed=‘left’
。而当closed=‘right’
面元的右边界是包含的,即00:00-00:05的区间中是包含00:05的。
ts.resample('5min',how='sum',closed='right')
1999-12-31 23:55:00 0
2000-01-01 00:00:00 15
2000-01-01 00:05:00 40
2000-01-01 00:10:00 11
Freq: 5T, dtype: int32
OHLC重采样
ts.resample('5min',how='ohlc')
通过groupby进行降采样
另一种降采样的方法:pandas的groupby方法。
rng=pd.date_range('1/1/2000',periods=100,freq='D')
ts=pd.Series(np.arange(len(rng)),index=rng)
ts
2000-01-01 0
2000-01-02 1
2000-01-03 2
2000-01-04 3
2000-01-05 4
..
2000-04-05 95
2000-04-06 96
2000-04-07 97
2000-04-08 98
2000-04-09 99
Freq: D, Length: 100, dtype: int32
ts.groupby(lambda x:x.month).mean()
1 15
2 45
3 75
4 95
dtype: int32
ts.groupby(lambda x:x.weekday).mean()
0 47.5
1 48.5
2 49.5
3 50.5
4 51.5
5 49.0
6 50.0
dtype: float64
升采样和插值
通过时期进行重采样
6 时间序列绘图
7 移动窗口函数
指数加权函数
二元移动窗口函数
用户定义的移动窗口函数