检查 Pandas DataFrame 中日期时间类型的两列之间的重叠

Checking overlaps between two columns of datetime type in Pandas DataFrame

我有一个包含两列的数据框,它们是日期时间对象(time_atime_b)。我需要逐行检查该行的 time_atime_b 的元素是否包含在另一个 time_atime_b 行。这就是我定义的“重叠”,如果 time_atime_b 之间的任何工作时间与其他时间间隔部分冲突,而不管房间如何。

我最初设法解决这个问题的方法是用 time_atime_b 的数据创建元组,然后逐行检查是否 time_atime_b 落在任何这些元组的范围内。

这种方法看起来很复杂,所以我想探索 Pandas 的力量。以 为例,我尝试根据我的问题调整它,使用名为 test_2 的数据框(列为 date, room, time_a, time_b, personnel_number),而 test_3 只有 time_atime_b 列。我这样写了我的部分解决方案:

any_in_range = lambda row, iterable: any(
    [(x > row[2]) & (x < row[3]) for x in iterable])
test_2['label_1'] = test_2.apply(any_in_range, iterable=test_3['time_case_finished'], axis=1)
test_2['label_2'] = test_2.apply(any_in_range, iterable=test_3['time_finished_cleaning'], axis=1)
test_2['isOverlap'] = np.where((test_2['label_1'] == True) | (test_2['label_2'] == True), 1, 0)
final_overlap = test_2[test_2['isOverlap'] == 1]

结果示例如下所述:

    date    room    time_a  time_b  personnel_number    label_1 label_2 isOverlap
77  2021-09-14  3   2021-09-14 12:01:42-07:00   2021-09-14 12:12:20-07:00   1   False   False   0
80  2021-09-14  1   2021-09-14 13:15:36-07:00   2021-09-14 13:24:50-07:00   1   False   False   0
83  2021-09-14  1   2021-09-14 14:21:52-07:00   2021-09-14 14:39:37-07:00   1   True    False   1
84  2021-09-14  3   2021-09-14 14:38:58-07:00   2021-09-14 14:52:24-07:00   1   True    True    1
90  2021-09-15  4   2021-09-15 09:25:11-07:00   2021-09-15 09:53:33-07:00   1   True    True    1
91  2021-09-15  5   2021-09-15 09:28:30-07:00   2021-09-15 09:42:25-07:00   1   False   False   0
92  2021-09-15  1   2021-09-15 09:52:18-07:00   2021-09-15 10:07:25-07:00   1   True    True    1
93  2021-09-15  3   2021-09-15 10:02:05-07:00   2021-09-15 10:20:13-07:00   1   False   True    1

现在,请注意第 90 行如何标记为 1,但我的代码未能找到它应该重叠的另一行(应该是第 91 行,标记为 0)。重叠并不完全,即使只是一分钟,我仍然想将其计入重叠,但我的代码并没有满足我数据集中每个案例的目的。

非常感谢任何帮助或建议。

问题似乎归结为找到重叠间隔,其中间隔由 time_atime_b

定义

这可以通过 piso(pandas 区间集操作)包有效解决,特别是 adjacency_matrix 方法

import pandas as pd
import piso

ii = pd.IntervalIndex.from_arrays(df["time_a"], df["time_b"])
df["isOverlap"] = piso.adjacency_matrix(ii).any(axis=1).astype(int).values