时间序列-时期及其运算

时期(Period)表示的是一个固定时间区间,比如数日、数月数季、数年等,例如一个账单是一段时间内的所有交易数据,这就是按月,季度等划分的固定时间区间。Period 类所表示的就是这种数据类型,其构造函数需要用到一个字符串或整数,以及频率:

import pandas as pd
from pandas import Series
import numpy as np
p = pd.Period(2012, freq="A-DEC")  #Period 对象表示的是从2012年1月1日到2012年12月31日之间的整段时间。
p
Period('2012', 'A-DEC')
p + 5
Period('2017', 'A-DEC')
p - 2
Period('2010', 'A-DEC')
pd.Period('2014', freq='A-DEC') - p
<2 * YearEnds: month=12>
#period_range 函数可用于创建规则的时期范围
rng = pd.period_range('1/1/2015','6/30/2015',freq='M') 
rng

PeriodIndex(['2015-01', '2015-02', '2015-03', '2015-04', '2015-05', '2015-06'], dtype='period[M]', freq='M')

PeriodIndex 类保存了一组 Period,它可以在任何 pandas 数据结构中被用作轴索引:

Series(np.random.randn(6), index = rng)

2015-01   -0.314419
2015-02   -0.655416
2015-03    1.868826
2015-04   -0.528982
2015-05    0.092287
2015-06    0.321132
Freq: M, dtype: float64
#PeriodIndex 类的构造函数还允许直接使用一组字符串
values = ['2001Q3', '2002Q2', '2003Q1']
index = pd.PeriodIndex(values, freq='Q-DEC')
index

PeriodIndex(['2001Q3', '2002Q2', '2003Q1'], dtype='period[Q-DEC]', freq='Q-DEC')

时期的频率转换

Period 和 PeriodIndex 对象都可以通过其 asfreq 方法被转换成别的频率。假设我们有一个年度时期,希望将其转换为当年年初或年末的一个月度时期:

p = pd.Period('2015', freq = 'A-DEC')

p.asfreq('M', how = 'start')

Period('2015-01', 'M')
p.asfreq('M',how='end')

Period('2015-12', 'M')

将 Period('2015','A-DEC')看做一个被划分为多个月度时期的时间段中的游标。对于一个不以12结束的财政年度,月度子时期的归属情况就不一样了:

p = pd.Period('2015', freq = 'A-JUN')
p

Period('2015', 'A-JUN')

在将高频率转换为低频率时,超时期(superperiod)是由子时期(subperiod)所属的位置决定的。例如,在 A-JUN 频率中,月份“2014年8月”实际上是属于周期“2015年”的:

p = pd.Period('2014-08','M')

p.asfreq('A-JUN')
 

#PeriodIndex 或 TimeSeries 的频率转换方式也是如此

rng = pd.period_range('2010','2015',freq='A-DEC')

ts = Series(np.random.randn(len(rng)),index=rng)

ts

2010    0.104686
2011   -0.458433
2012   -0.760378
2013    1.815320
2014    0.005840
2015   -0.794424
Freq: A-DEC, dtype: float64
ts.asfreq('M',how='start')

2010-01    0.104686
2011-01   -0.458433
2012-01   -0.760378
2013-01    1.815320
2014-01    0.005840
2015-01   -0.794424
Freq: M, dtype: float64
ts.asfreq('B',how='end')

2010-12-31    0.104686
2011-12-30   -0.458433
2012-12-31   -0.760378
2013-12-31    1.815320
2014-12-31    0.005840
2015-12-31   -0.794424
Freq: B, dtype: float64

3

季度型数据在会计、金融等领域中很常见。许多季度型数据都会涉及“财年末”的概念,通常是一年12个月中某月的最后一个日历日或工作日。就这一点来说,时期“2012Q4”根据财年末的不同会有不同的含义。pandas 支持12种可能的季度型频率,即 Q-JAN 到 Q-DEC:

p = pd.Period('2012Q4', freq='Q-JAN')
p

Period('2012Q4', 'Q-JAN')
p.asfreq('D','start')

Period('2011-11-01', 'D')
p.asfreq('D','end')

Period('2012-01-31', 'D')

因此,Period 之间的算术运算会非常简单。例如,要获取该季度倒数第二个工作日下午4点的时间戳,我们可以这样:

p4pm = (p.asfreq('B','e')-1).asfreq('T','s')+16*60
p4pm

Period('2012-01-30 16:00', 'T')
p4pm.to_timestamp()

Timestamp('2012-01-30 16:00:00')

period_range 还可以用于生成季度型范围。季度型范围的算术运算也跟上面是一样的:

rng = pd.period_range('2014Q3','2015Q4',freq='Q-JAN') 

ts = Series(np.arange(len(rng)), index = rng)

ts

2014Q3    0
2014Q4    1
2015Q1    2
2015Q2    3
2015Q3    4
2015Q4    5
Freq: Q-JAN, dtype: int64
new_rng = (rng.asfreq('B','e')-1).asfreq('T','s')+16*60 

ts.index = new_rng.to_timestamp()

ts

2013-10-30 16:00:00    0
2014-01-30 16:00:00    1
2014-04-29 16:00:00    2
2014-07-30 16:00:00    3
2014-10-30 16:00:00    4
2015-01-29 16:00:00    5
dtype: int64

4 将 Timestamp 转换为 Period(及其反向过程)

rng = pd.date_range('1/1/2000',periods=3,freq='M')

ts = Series(np.random.randn(3),index=rng)

pts=ts.to_period()

ts


2000-01-31   -2.054633
2000-02-29   -0.650259
2000-03-31   -1.125433
Freq: M, dtype: float64
pts

2000-01   -2.054633
2000-02   -0.650259
2000-03   -1.125433
Freq: M, dtype: float64

由于时期指的是非重叠时间区间,因此对于给定的频率,一个时间戳只能属于一个时期。新 PeriodIndex 的频率默认是从时间戳推断而来的,你也可以指定任何别的频率。结果中允许存在重复时期:

rng = pd.date_range('1/29/2000',periods=6,freq='D')

ts2 = Series(np.random.randn(6), index=rng)

ts2.to_period('M')

2000-01    0.888082
2000-01   -1.252855
2000-01   -2.822398
2000-02   -1.185904
2000-02   -0.121582
2000-02    0.198893
Freq: M, dtype: float64

要转换为时间戳,使用 to_timestamp 即可


pts = ts.to_period()
pts

2000-01   -2.054633
2000-02   -0.650259
2000-03   -1.125433
Freq: M, dtype: float64
pts.to_timestamp(how='end')

2000-01-31 23:59:59.999999999   -2.054633
2000-02-29 23:59:59.999999999   -0.650259
2000-03-31 23:59:59.999999999   -1.125433
Freq: M, dtype: float64

通过数组创建PeriodIndex

某些数据集中时间信息是分开在多个列存放的,可以通过PeriodIndex的参数将这些列组合在一起

year = [2017,2017,2017,2017,2018,2018,2018,2018]
quarter = [1,2,3,4,1,2,3,4]
index = pd.PeriodIndex(year=year,quarter=quarter,freq='Q-DEC')
index 

PeriodIndex(['2017Q1', '2017Q2', '2017Q3', '2017Q4', '2018Q1', '2018Q2',
             '2018Q3', '2018Q4'],
            dtype='period[Q-DEC]', freq='Q-DEC')

你可能感兴趣的:(时间序列-时期及其运算)