看过来
《pandas 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
Pandas 专门提供了一个时间偏移对象(Date offsets)来完成时间偏移工作,本文将介绍 Date offsets 的构成和使用方法。DateOffset 基础操作类似于 dateutil.relativedelta
(relativedelta 文档),可以按真实的日历进行时间偏移,并用算数运算符(+)或 apply 进行日期偏移操作。
所有的日期偏移对象都在 pandas.tseries.offsets
下,其中 pandas.tseries.offsets.DateOffset
是标准的日期范围时间偏移类型,用于日期范围的标准日期增量类型。它默认是一个日历日。
from pandas.tseries.offsets import DateOffset
ts = pd.Timestamp('2017-01-01 09:10:11')
ts + DateOffset(months=3)
# Timestamp('2017-04-01 09:10:11')
ts + DateOffset(hours=2)
# Timestamp('2017-01-01 11:10:11')
ts + DateOffset()
# Timestamp('2017-01-02 09:10:11')
DateOffset 基本都支持频率字符串或偏移别名,传入 freq 参数。以下都是时间偏移的子类、子对象,都支持时间偏移的相关操作。有效的日期偏移及频率字符串有:
日期偏移对象 | 频率字符串 | 说明 |
---|---|---|
DateOffset | 无 | 通用偏移类,默认一个日历日 |
BDay 或 BusinessDay | 'B' | 工作日 |
CDay 或 CustomBusinessDay | 'C' | 自定义工作日 |
Week | 'W' | 一周,可选周内固定某日 |
WeekOfMonth | 'WOM' | 每月第几周的第几天 |
LastWeekOfMonth | 'LWOM' | 每月最后一周的第几天 |
MonthEnd | 'M' | 日历日月末 |
MonthBegin | 'MS' | 日历日月初 |
BMonthEnd 或 BusinessMonthEnd | 'BM' | 工作日月末 |
BMonthBegin 或 BusinessMonthBegin | 'BMS' | 工作日月初 |
CBMonthEnd 或 CustomBusinessMonthEnd | 'CBM' | 自定义工作日月末 |
CBMonthBegin 或 CustomBusinessMonthBegin | 'CBMS' | 自定义工作日月初 |
SemiMonthEnd | 'SM' | 某月第 15 天(或其它半数日期)与日历日月末 |
SemiMonthBegin | 'SMS' | 日历日月初与第 15 天(或其它半数日期) |
QuarterEnd | 'Q' | 日历日季末 |
QuarterBegin | 'QS' | 日历日季初 |
BQuarterEnd | 'BQ | 工作日季末 |
BQuarterBegin | 'BQS' | 工作日季初 |
FY5253Quarter | 'REQ' | 零售季,又名 52-53 周 |
YearEnd | 'A' | 日历日年末 |
YearBegin | 'AS' 或 'BYS' | 日历日年初 |
BYearEnd | 'BA' | 工作日年末 |
BYearBegin | 'BAS' | 工作日年初 |
FY5253 | 'RE' | 零售年(又名 52-53 周) |
Easter | 无 | 复活节假日 |
BusinessHour | 'BH' | 工作小时 |
CustomBusinessHour | 'CBH' | 自定义工作小时 |
Day | 'D' | 一天 |
Hour | 'H' | 一小时 |
Minute | 'T' 或 'min' | 一分钟 |
Second | 'S' | 一秒 |
Milli | 'L' 或 'ms' | 一毫秒 |
Micro | 'U' 或 'us' | 一微秒 |
Nano | 'N' | 一纳秒 |
Offset 支持向前或向后偏移:
ts = pd.Timestamp('2020-06-06 00:00:00')
ts.day_name()
# 'Saturday'
# 定义一个工作小时偏移,默认是周一到周五 9-17 点,我们从 10点开始
offset = pd.offsets.BusinessHour(start='10:00')
# 向前偏移一个工作小时,是一个周一,跳过了周日
offset.rollforward(ts)
# Timestamp('2020-06-08 10:00:00')
# 向前偏移至最近的工作日,小时也会增加
ts + offset
# Timestamp('2020-06-08 11:00:00')
# 向后偏移,会在周五下班前的一个小时
offset.rollback(ts)
# Timestamp('2020-06-05 17:00:00')
ts - pd.offsets.Day(1) # 昨日
ts - pd.offsets.Day(2) # 前日
ts - pd.offsets.Week(weekday=0) - pd.offsets.Day(14) # 上周一
ts - pd.offsets.MonthEnd() - pd.offsets.MonthBegin() # 上月一日
时间偏移操作会保留小时和分钟,有时候我们不在意具体的时间只开始从哪天开始,可以使用 normalize()
进行标准化到午夜 0 点:
offset.rollback(ts).normalize()
# Timestamp('2020-06-05 00:00:00')
下文会再次介绍。
apply
可以使用偏移对象应用到一个时间上:
ts = pd.Timestamp('2020-06-01 09:00')
day = pd.offsets.Day() # 定义偏移对象
day.apply(ts) # 偏移对象应用到时间上
# Timestamp('2020-06-02 09:00:00')
day.apply(ts).normalize() # 标准化/归一化
# Timestamp('2020-06-02 00:00:00')
ts = pd.Timestamp('2020-06-01 22:00')
hour = pd.offsets.Hour()
hour.apply(ts)
# Timestamp('2020-06-01 23:00:00')
hour.apply(ts).normalize()
# Timestamp('2020-06-01 00:00:00')
hour.apply(pd.Timestamp("2014-01-01 23:30")).normalize()
# Timestamp('2014-01-02 00:00:00')
上边我们偏移时只偏移了偏移对象的一个单位,可以传入参数支持多个单位和对象中的其他单位:
import datetime
d = datetime.datetime(2020, 6, 1, 9, 0)
# datetime.datetime(2020, 6, 1, 9, 0)
d + pd.offsets.Week() # 偏移一周
# Timestamp('2020-06-08 09:00:00')
d + pd.offsets.Week(weekday=4) # 偏移4个周中的日期
# Timestamp('2020-06-05 09:00:00')
# 取一周第几天
(d + pd.offsets.Week(weekday=4)).weekday()
# 4
d - pd.offsets.Week() # 向后一周
# Timestamp('2020-05-25 09:00:00')
参数也支持归一标准化 normalize
:
d + pd.offsets.Week(normalize=True)
# Timestamp('2020-06-08 00:00:00')
d - pd.offsets.Week(normalize=True)
# Timestamp('2020-05-25 00:00:00')
再比如,YearEnd
支持 month
指定月份:
d + pd.offsets.YearEnd()
# Timestamp('2020-12-31 09:00:00')
d + pd.offsets.YearEnd(month=6)
# Timestamp('2020-06-30 09:00:00')
不同的偏移对象支持不同的参数,可以通过代码编辑器的代码提示进行查询。
当使用日期作为索引的DataFrame时,此函数可以基于日期偏移量选择最后几行:
i = pd.date_range('2018-04-09', periods=4, freq='2D')
ts = pd.DataFrame({'A': [1, 2, 3, 4]}, index=i)
ts
'''
A
2018-04-09 1
2018-04-11 2
2018-04-13 3
2018-04-15 4
'''
# 取最后三天, 请注意,返回的是最近3天的数据
# 而不是数据集中最近3天的数据,因此未返回2018-04-11的数据
ts.last('3D')
'''
A
2018-04-13 3
2018-04-15 4
'''
# 前三天
ts.first('3D')
'''
A
2018-04-09 1
2018-04-11 2
'''
# 指定时间
ts.at_time('12:00')
'''
A
2018-04-09 12:00:00 2
2018-04-10 12:00:00 4
'''
ts.between_time('0:15', '0:45')
'''
A
2018-04-10 00:20:00 2
2018-04-11 00:40:00 3
'''
ts.between_time('0:45', '0:15')
'''
A
2018-04-09 00:00:00 1
2018-04-12 01:00:00 4
'''
更新时间:2020-10-30 19:21:11 标签:pandas 时间偏移 对象