Python Pandas – 返回给定CustomBusinessDay Offset对象应用的频率,表示为字符串
Pandas是Python中非常常用的用于数据探索、数据清理和数据处理的库之一。在Pandas中,日期时间处理是重要的功能之一。Pandas提供了丰富的工具来处理不同类型的日期时间数据,包括时间戳、时间差、时间段和偏移量等。在实际使用中,我们可能需要对日期时间数据进行一些特殊的处理,这就需要用到时间偏移(offset)。
在Pandas中,时间偏移(offset)是由若干个特定偏移量(base offset)组成的,用于表示某种时间段的规律性,比如每周、每月、每季度等。Pandas提供了一些常用的时间偏移(offset),比如BusinessDay、Week、MonthBegin等。除此之外,我们还可以通过自定义偏移量的方式,来满足一些特殊的需求。这就是本文要介绍的CustomBusinessDay。
CustomBusinessDay是一个由用户自定义的业务日偏移(offset)。比如,我们可能需要定义一个自定义的业务日偏移(offset),表示每个月的第二个和第四个工作日。这个偏移(offset)可以作为Pandas的DateOffset的参数使用,用于对日期时间数据进行操作。
下面我们就来看一下如何使用CustomBusinessDay,并返回所应用的频率。
CustomBusinessDay的基本使用
我们首先需要导入pandas和CustomBusinessDay:
import pandas as pd
from pandas.tseries.offsets import CustomBusinessDay
下面我们定义一个自定义的业务日偏移(offset),表示每月第二个和第四个周一至周四:
# 定义自定义时间偏移(offset)
weekdays = pd.offsets.Week(weekday=0)
CustomBusinessDay(weekmask='Mon Tue Wed Thu Fri', holidays=None, weekoffsets=[1,3])
这里,我们用pd.offsets.Week来表示每周,weekday=0表示周一,这样weekdays就表示了每个周一。然后,我们使用CustomBusinessDay,传入weekmask=’Mon Tue Wed Thu Fri’表示从周一到周五算工作日,holidays=None表示没有节假日,weekoffsets=[1,3]表示每个月的第二个和第四个workday。这样,我们就成功定义了一个自定义的业务日偏移(offset)。
接下来,我们可以用offset.rollforward和offset.rollback来依次计算日期时间数据在自定义业务日偏移(offset)中向前和向后的日期时间。比如,假设我们从’2022-05-12’开始向前推10个工作日:
# 定义自定义时间偏移(offset)
weekdays = pd.offsets.Week(weekday=0)
biz_day = CustomBusinessDay(weekmask='Mon Tue Wed Thu Fri', holidays=None, weekoffsets=[1,3])
start_date = '2022-05-12'
dates = pd.date_range(start=start_date, periods=10, freq=biz_day)
dates
这里,我们用pd.date_range来生成从’2022-05-12’开始的10个工作日的日期时间数据。输出结果为:
DatetimeIndex(['2022-05-12', '2022-05-13', '2022-05-16', '2022-05-18',
'2022-05-26', '2022-05-27', '2022-05-30', '2022-06-01',
'2022-06-08', '2022-06-09'],
dtype='datetime64[ns]', freq='CBMonthEnd(offsets=[<CustomBusinessDay>])')
可以看到,除了每个月的第二个和第四个工作日之外,其他的工作日都被排除了。
返回自定义业务日偏移(offset)的频率
我们可以使用offset.freqstr来返回自定义业务日偏移(offset)的频率,表示为字符串。
biz_day.freqstr
这里,我们可以看到,自定义的业务日偏移(offset)的频率为’CBMonthEnd’,表示每个月的第二个和第四个工作日。
更复杂的自定义业务日偏移(offset)
除了上面的例子之外,我们还可以用更复杂的方式来定义自定义业务日偏移(offset)。比如,如果我们需要定义一个自定义偏移量,表示每个月的最后一个工作日和第一个工作日,则可以使用下面的代码:
class LastThenFirstBusinessDay(CustomBusinessDay):
def __init__(self, n=1, offset=None, normalize=False, month_end=True):
super().__init__(weekmask='Mon Tue Wed Thu Fri', holidays=None, month_end=month_end)
self.n = n
self.offset = offset
self.normalize = normalize
def apply(self, other):
f = self.offset.apply if self.offset else lambda x: x
n = self.n
pt = pd.Timestamp(other)
if self.month_end and pt.month == (pt + pd.DateOffset(days=n)).month:
pt = pt + pd.DateOffset(months=1)
pt = pt.replace(day=1)
pt += self.offset.apply(pd.DateOffset(days=n))
while not self.onOffset(pt):
pt += self.offset.apply(pd.DateOffset(days=1))
if self.normalize:
pt = self.normalizeDate(pt)
return pt
这里,我们定义了一个名为LastThenFirstBusinessDay的类,继承了CustomBusinessDay,并重写了init和apply方法。在init方法中,我们额外定义了参数n、offset、normalize和month_end。n表示向前或向后推n个工作日,offset表示时间偏移(offset),normalize表示是否归一化,month_end表示是否包含每个月的最后一个工作日。
在apply方法中,我们先调用了父类CustomBusinessDay中的apply方法来计算出当前日期时间数据向前或向后推n个工作日的日期时间,然后在while循环中,通过offset.apply(pd.DateOffset(days=1))来不断向前或向后推一天,直到计算出的日期时间满足我们自定义的业务日偏移(offset)。
使用LastThenFirstBusinessDay自定义业务日偏移(offset)时,代码可以如下:
# 定义自定义时间偏移(offset)
custom_offset = LastThenFirstBusinessDay(n=-1, month_end=True, offset=None, normalize=False)
start_date = '2022-05-12'
dates = pd.date_range(start=start_date, periods=10, freq=custom_offset)
dates
这里,我们用pd.date_range来生成从’2022-05-12’开始的10个日期时间数据。自定义的业务日偏移(offset)指定了n=-1表示向前推1个工作日,month_end=True表示包含每个月的最后一个工作日。
结论
本文介绍了如何使用CustomBusinessDay自定义业务日偏移(offset)以及如何返回应用该偏移(offset)的频率表示为字符串。除此之外,我们还以一个例子介绍了如何使用自定义的类来实现更复杂的自定义业务日偏移(offset)。通过本文的学习,读者可以更加深入理解Pandas中日期时间处理的相关知识,以及如何应用这些知识来满足不同的需求。
极客笔记