Python数据分析 | (34) 日期的范围、频率以及移动

pandas中的原生时间序列一般被认为是不规则的,也就是说,它们没有固定 的频率。对于大部分应用程序而言,这是无所谓的。但是,它常常需要以某 种相对固定的频率进行分析,比如每日、每月、每15分钟等(这样自然会在 时间序列中引入缺失值)。幸运的是,pandas有一整套标准时间序列频率以 及用于重采样、频率推断、生成固定频率日期范围的工具。例如,我们可以 将之前那个时间序列转换为一个具有固定频率(每日)的时间序列,只需调 用resample即可:

import numpy as np
import pandas as pd
np.random.seed(12345)
import matplotlib.pyplot as plt
plt.rc('figure', figsize=(10, 6))
PREVIOUS_MAX_ROWS = pd.options.display.max_rows
pd.options.display.max_rows = 20
np.set_printoptions(precision=4, suppress=True)
from datetime import datetime
dates = [datetime(2011, 1, 2), datetime(2011, 1, 5),
         datetime(2011, 1, 7), datetime(2011, 1, 8),
         datetime(2011, 1, 10), datetime(2011, 1, 12)]
ts = pd.Series(np.random.randn(6), index=dates)
ts

resampler = ts.resample('D')

字符串“D”是每天的意思。

频率的转换(或重采样)是一个比较大的主题,之后将专门用一节来进行讨论。这里,我将告诉你如何使用基本的频率和它的倍数。

目录

1. 生成日期范围

2. 频率和日期偏移量

3. 移动(超前和滞后)数据


1. 生成日期范围

虽然我之前用的时候没有明说,但你可能已经猜到pandas.date_range可用 于根据指定的频率生成指定长度的DatetimeIndex:

index = pd.date_range('2012-04-01', '2012-06-01')
index

默认情况下,date_range会产生按天计算的时间点。如果只传入起始或结束 日期,那就还得传入一个表示一段时间的数字:

print(pd.date_range(start='2012-04-01', periods=20))
pd.date_range(end='2012-06-01', periods=20)

起始和结束日期定义了日期索引的严格边界。例如,如果你想要生成一个由每月最后一个工作日组成的日期索引,可以传入"BM"频率(表示business end of month,下表是频率列表),这样就只会包含时间间隔内(或刚好 在边界上的)符合频率要求的日期:

pd.date_range('2000-01-01', '2000-12-01', freq='BM')

date_range默认会保留起始和结束时间戳的时间信息(如果有的话):

pd.date_range('2012-05-02 12:56:31', periods=5)

有时,虽然起始和结束日期带有时间信息,但你希望产生一组被规范化 (normalize)到午夜的时间戳。normalize选项即可实现该功能:

pd.date_range('2012-05-02 12:56:31', periods=5, normalize=True)

 

2. 频率和日期偏移量

pandas中的频率是由一个基础频率(base frequency)和一个乘数组成的。 基础频率通常以一个字符串别名表示,比如"M"表示每月,"H"表示每小时。 对于每个基础频率,都有一个被称为日期偏移量(date offset)的对象与之 对应。例如,按小时计算的频率可以用Hour类表示:

from pandas.tseries.offsets import Hour, Minute
hour = Hour()
hour

传入一个整数即可定义偏移量的倍数:

four_hours = Hour(4)
four_hours

一般来说,无需明确创建这样的对象,只需使用诸如"H"或"4H"这样的字符串 别名即可。在基础频率前面放上一个整数即可创建倍数:

pd.date_range('2000-01-01', '2000-01-03 23:59', freq='4h')

大部分偏移量对象都可通过加法进行连接:

Hour(2) + Minute(30)

同理,你也可以传入频率字符串(如"2h30min"),这种字符串可以被高效地 解析为等效的表达式:

pd.date_range('2000-01-01', periods=10, freq='1h30min')

有些频率所描述的时间点并不是均匀分隔的。例如,"M"(日历月末) 和"BM"(每月最后一个工作日)就取决于每月的天数,对于后者,还要考虑 月末是不是周末。由于没有更好的术语,我将这些称为锚点偏移量 (anchored offset)。

用户可以根据实际需求自定义一些频率类以便提供pandas所没有 的日期逻辑,但具体的细节超出了本博客的范围。

时间序列的基础频率:

  • WOM日期

WOM(Week Of Month)是一种非常实用的频率类,它以WOM开头。它使你能获得诸如“每月第3个星期五”之类的日期:

rng = pd.date_range('2012-01-01', '2012-09-01', freq='WOM-3FRI')
list(rng)

 

3. 移动(超前和滞后)数据

移动(shifting)指的是沿着时间轴将数据前移或后移。Series和DataFrame都有一个shift方法用于执行单纯的前移或后移操作,保持索引不变:

ts = pd.Series(np.random.randn(4),
               index=pd.date_range('1/1/2000', periods=4, freq='M'))
print(ts)
print("---------------")
print(ts.shift(2))
ts.shift(-2)

当我们这样进行移动时,就会在时间序列的前面或后面产生缺失数据。

shift通常用于计算一个时间序列或多个时间序列(如DataFrame的列)中的 百分比变化。可以这样表达:

ts/ts.shift(1) - 1

由于单纯的移位操作不会修改索引,所以部分数据会被丢弃。因此,如果频 率已知,则可以将其传给shift以便实现对时间戳进行位移而不是对数据进行 简单位移:

ts.shift(2, freq='M')

这里还可以使用其他频率,于是你就能非常灵活地对数据进行超前和滞后处理了:

print(ts)
print("--------------")
print(ts.shift(3, freq='D'))
ts.shift(1, freq='90T')

  • 通过偏移量对日期进行位移

pandas的日期偏移量还可以用在datetime或Timestamp对象上:

from pandas.tseries.offsets import Day, MonthEnd
now = datetime(2011, 11, 17)
now + 3 * Day()

如果加的是锚点偏移量(比如MonthEnd),第一次增量会将原日期向前滚动 到符合频率规则的下一个日期:

print(now + MonthEnd())
now + MonthEnd(2)

通过锚点偏移量的rollforward和rollback方法,可明确地将日期向前或向后“滚 动”:

offset = MonthEnd()
print(offset.rollforward(now)) #向前 向未来
offset.rollback(now)

日期偏移量还有一个巧妙的用法,即结合groupby使用这两个“滚动”方法:

ts = pd.Series(np.random.randn(20),
               index=pd.date_range('1/15/2000', periods=20, freq='4d'))
print(ts)
ts.groupby(offset.rollforward).mean()

当然,更简单、更快速地实现该功能的办法是使用resample(之后会详细讲解):

ts.resample('M').mean() #各月数据求均值

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值