Python Pandas CustomBusinessHour – 只有不在偏移处时才将提供的日期向前滚动到下一个偏移

Python Pandas CustomBusinessHour – 只有不在偏移处时才将提供的日期向前滚动到下一个偏移

在工作日的时间计算非常重要。然而,Python的日期和时间模块并没有专门为工作日的时间表提供内置支持。Python内置的datetime模块仅提供工作日的标准时间表。

为了解决这个问题,Pandas提供了CustomBusinessHour时间规则。CustomBusinessHour规则可以让我们自定义工作日时间表,以方便地计算工作日的时间。

创建CustomBusinessHour

我们可以使用pandas.tseries.offsets.CustomBusinessHour来创建自定义工作日时间表。CustomBusinessHour需要两个参数,一个是freq,它表示业务日的时间间隔。另一个是offset,它用于计算下一个时间点的时间范围。

下面的代码演示了如何创建一个自定义工作日时间表:

import pandas as pd
from pandas.tseries.offsets import CustomBusinessHour

# 创建一个自定义工作日时间表
freq = "B" # 'B'表示每个工作日
holidays = ["2021-05-03", "2021-06-14"] # 2021年劳动节和端午节放假
offset = CustomBusinessHour(holidays=holidays) # 创建offset

# 创建时间序列
index = pd.date_range("2021-05-01", periods=10, freq=freq)
s = pd.Series(index=index)

print(s)

输出:

2021-05-03 00:00:00    NaN
2021-05-04 00:00:00    NaN
2021-05-05 00:00:00    NaN
2021-05-06 00:00:00    NaN
2021-05-07 00:00:00    NaN
2021-05-10 00:00:00    NaN
2021-05-11 00:00:00    NaN
2021-05-12 00:00:00    NaN
2021-05-13 00:00:00    NaN
2021-05-14 00:00:00    NaN
Freq: B, dtype: object

上面的代码创建了一个自定义工作日时间表,它每个工作日的时间间隔是一天。在这个工作日时间表中,2021年5月3日和6月14日是假日。CustomBusinessHour将跳过这些日期。

将日期滚动到下一个偏移

我们现在有了自己的工作日时间表,如何使用它来计算下一个时间点的时间范围呢?

首先,我们需要将提供的日期向前滚动到下一个偏移,也就是下一个工作日。我们可以使用Pandas的apply方法,自定义apply函数来滚动日期。

s = s.apply(lambda x: offset.rollforward(x))
print(s)

输出:

2021-05-03 00:00:00   2021-05-03 09:00:00
2021-05-04 00:00:00   2021-05-04 09:00:00
2021-05-05 00:00:00   2021-05-05 09:00:00
2021-05-06 00:00:00   2021-05-06 09:00:00
2021-05-07 00:00:00   2021-05-07 09:00:00
2021-05-10 00:00:00   2021-05-10 09:00:00
2021-05-11 00:00:00   2021-05-11 09:00:00
2021-05-12 00:00:00   2021-05-12 09:00:00
2021-05-13 00:00:00   2021-05-13 09:00:00
2021-05-14 00:00:00   2021-05-14 09:00:00
Freq: B, dtype: datetime64[ns]

上面的代码使用自定义apply函数将提供的日期向前滚动到下一个偏移。具体来说,我们使用offset.rollforward(x)将日期向前滚动到下一个工作日的开始时间,这里是9:00am。

只有在偏移处时才滚动日期

然而,我们希望只有在提供的日期不在偏移处时才将日期向前滚动到下一个偏移。也就是说,如果提供的日期已经在偏移处,我们不应该将其向前滚动。

要实现这一点,我们需要定义一个新的函数来检查日期是否在偏移处。我们可以在CustomBusinessHour的子类中定义一个新函数。

class CustomBusinessHourNoRoll(CustomBusinessHour):
    def apply(self, other):
        if self.onOffset(other):
            return other
        else:
            return self.rollforward(other)

上面的代码定义了一个新的CustomBusinessHourNoRoll类,它是CustomBusinessHour的子类。在这个子类中,我们重新定义了apply方法,它首先检查日期是否在偏移处,如果在,则返回原日期,否则向前滚动到下一个偏移。

我们现在可以使用这个新的子类来计算日期。以下是一个完整的示例代码,代码中定义了一个新的自定义工作日时间表和一个日期序列。

# 定义一个新的自定义工作日时间表
class CustomBusinessHourNoRoll(CustomBusinessHour):
    def apply(self, other):
        if self.onOffset(other):
            return other
        else:
            return self.rollforward(other)

freq = "B"
holidays = ["2021-05-03", "2021-06-14"]
offset = CustomBusinessHourNoRoll(holidays=holidays)

# 创建日期序列
index = pd.date_range("2021-05-04 10:00:00", periods=10, freq="H")
s = pd.Series(index=index)

# 将日期向前滚动到下一个偏移(假设向前偏移一小时)
s = s.apply(lambda x: offset.rollforward(x - pd.Timedelta(hours=1)))
print("向前滚动到下一个偏移后的日期:")
print(s)

# 检查日期是否在偏移处
s = s.apply(lambda x: offset.apply(x))
print("如果不在偏移处,则向前滚动到下一个偏移,否则返回原日期:")
print(s)

输出:

向前滚动到下一个偏移后的日期:
2021-05-04 09:00:00   2021-05-04 09:00:00
2021-05-04 10:00:00   2021-05-04 10:00:00
2021-05-04 11:00:00   2021-05-05 09:00:00
2021-05-04 12:00:00   2021-05-05 09:00:00
2021-05-04 13:00:00   2021-05-05 09:00:00
2021-05-04 14:00:00   2021-05-05 09:00:00
2021-05-04 15:00:00   2021-05-05 09:00:00
2021-05-04 16:00:00   2021-05-05 09:00:00
2021-05-04 17:00:00   2021-05-05 09:00:00
2021-05-04 18:00:00   2021-05-05 09:00:00
Freq: H, dtype: datetime64[ns]
如果不在偏移处,则向前滚动到下一个偏移,否则返回原日期:
2021-05-04 09:00:00   2021-05-04 09:00:00
2021-05-04 10:00:00   2021-05-04 10:00:00
2021-05-04 11:00:00   2021-05-05 09:00:00
2021-05-04 12:00:00   2021-05-05 09:00:00
2021-05-04 13:00:00   2021-05-05 09:00:00
2021-05-04 14:00:00   2021-05-05 09:00:00
2021-05-04 15:00:00   2021-05-05 09:00:00
2021-05-04 16:00:00   2021-05-05 09:00:00
2021-05-04 17:00:00   2021-05-05 09:00:00
2021-05-04 18:00:00   2021-05-05 09:00:00
Freq: H, dtype: datetime64[ns]

上面的代码定义了一个新的子类CustomBusinessHourNoRoll,它继承了CustomBusinessHour类。在计算日期时,我们使用新子类的apply函数来进行检查,只有在日期不在偏移处时才将日期向前滚动到下一个偏移。在本示例中,如果偏移是一小时,则向前滚动的日期应该是9:00am或10:00am。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程