检查 Pandas DataFrame 中日期时间类型的两列之间的重叠
Checking overlaps between two columns of datetime type in Pandas DataFrame
我有一个包含两列的数据框,它们是日期时间对象(time_a
和 time_b
)。我需要逐行检查该行的 time_a
或 time_b
的元素是否包含在另一个 time_a
和 time_b
行。这就是我定义的“重叠”,如果 time_a
或 time_b
之间的任何工作时间与其他时间间隔部分冲突,而不管房间如何。
我最初设法解决这个问题的方法是用 time_a
和 time_b
的数据创建元组,然后逐行检查是否 time_a
或 time_b
落在任何这些元组的范围内。
这种方法看起来很复杂,所以我想探索 Pandas 的力量。以 为例,我尝试根据我的问题调整它,使用名为 test_2
的数据框(列为 date, room, time_a, time_b, personnel_number
),而 test_3
只有 time_a
,time_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_a
和 time_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
我有一个包含两列的数据框,它们是日期时间对象(time_a
和 time_b
)。我需要逐行检查该行的 time_a
或 time_b
的元素是否包含在另一个 time_a
和 time_b
行。这就是我定义的“重叠”,如果 time_a
或 time_b
之间的任何工作时间与其他时间间隔部分冲突,而不管房间如何。
我最初设法解决这个问题的方法是用 time_a
和 time_b
的数据创建元组,然后逐行检查是否 time_a
或 time_b
落在任何这些元组的范围内。
这种方法看起来很复杂,所以我想探索 Pandas 的力量。以 test_2
的数据框(列为 date, room, time_a, time_b, personnel_number
),而 test_3
只有 time_a
,time_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_a
和 time_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