Python Pandas – 检查是否已将CustomBusinessHour Offset归一化

Python Pandas – 检查是否已将CustomBusinessHour Offset归一化

什么是CustomBusinessHour Offset

在介绍 CustomBusinessHour 的归一化之前,我们先来看看什么是 CustomBusinessHour Offset

当我们处理时间序列数据时,经常需要考虑工作日、节假日等因素对数据造成的影响。Pandas 提供了一个 CustomBusinessHour 类型,来帮助我们处理这种情况。它可以指定一周中的工作日、休息日,以及每日的工作开始时间和结束时间。

例如,我们可以定义一个 CustomBusinessHour 来表示周一至周五的 9:00 到 17:00 是工作时间,而周六周日是休息时间:

from pandas.tseries.offsets import CustomBusinessHour

work_hours = CustomBusinessHour(
    weekmask='Mon Tue Wed Thu Fri',
    start='09:00',
    end='17:00'
)

这样,我们就可以将一个时间戳向前或向后移动指定数量的工作小时:

from datetime import datetime

start_time = datetime(2022, 1, 1, 10, 0)
end_time = start_time + work_hours * 2  # 向后移动 2 个工作小时

CustomBusinessHour Offset 的归一化

当我们使用 CustomBusinessHour 类型来处理时间序列数据时,经常会遇到一个问题:不同的时间戳,可能会落在同一个工作小时内。例如,假设我们有两个时间戳,分别是 2022-01-03 10:30 和 2022-01-03 11:30,它们都落在周一的工作时间内。如果我们直接将它们转换成工作小时的数量,得到的结果是相同的:

from datetime import datetime

start_time_1 = datetime(2022, 1, 3, 10, 30)
start_time_2 = datetime(2022, 1, 3, 11, 30)

print(work_hours.count(start_time_1, start_time_2))  # 输出 1

这可能会导致一些问题,因为这两个时间戳实际上属于不同的工作小时。为了处理这种情况,Pandas 引入了 CustomBusinessHour 的归一化。归一化后,不同的时间戳总是在不同的工作小时内。

例如,我们对上面的例子进行归一化:

normalized_start_time_1 = work_hours.normalize(start_time_1)
normalized_start_time_2 = work_hours.normalize(start_time_2)

print(work_hours.count(normalized_start_time_1, normalized_start_time_2))  # 输出 2

可以看到,经过归一化后,这两个时间戳被分成了两个工作小时。这个例子中只有两个时间戳,但是在实际应用中,时间戳数量可能会非常多,因此归一化是非常重要的。

如何检查是否已将CustomBusinessHour Offset归一化

通常情况下,我们可以通过检查归一化后的 CustomBusinessHour 对象是否等于原始的 CustomBusinessHour 对象,来判断是否已将 CustomBusinessHour 归一化。如果它们相等,说明没有进行归一化,否则就进行了归一化。

例如,对于前面定义的 work_hours,我们可以这样检查它是否已经归一化:

normalized_work_hours = work_hours.normalize()

print(work_hours == normalized_work_hours)  # 输出 False

结果为 False,说明 work_hours 已经进行了归一化。如果返回值为 True,则说明还没有进行归一化。

需要注意的是,上面的检查方式对于大部分情况都是有效的,但是也有一些特殊情况,例如如果在定义 CustomBusinessHour 对象时指定了自定义假期,那么归一化后的对象就不等于原始对象,因为归一化会忽略假期的影响。在这种情况下,可以通过检查两个对象的 times 属性是否相等来确定是否进行了归一化:

from pandas.tseries.holiday import USFederalHolidayCalendar

cal = USFederalHolidayCalendar()

work_hours_with_holidays = CustomBusinessHour(
    weekmask='Mon Tue Wed Thu Fri',
    start='09:00',
    end='17:00',
    holidays=cal.holidays()
)

normalized_work_hours_with_holidays = work_hours_with_holidays.normalize()

print(work_hours_with_holidays.times == normalized_work_hours_with_holidays.times)  # 输出 True

结论

在处理时间序列数据时,使用 CustomBusinessHour 可以方便地处理工作日、休息日等诸多问题。但是由于存在归一化的问题,我们需要在使用时注意检查对象是否已经归一化,以避免出现问题。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程