【问题标题】:Checking overlaps between two columns of datetime type in Pandas DataFrame检查 Pandas DataFrame 中两列日期时间类型的重叠
【发布时间】:2022-06-21 11:53:59
【问题描述】:

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

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

这种方法看起来很复杂,所以我想为此目的探索 Pandas 的力量。以this great question 为例,我尝试使用名为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)。重叠不是全部,即使只是一分钟,我仍然想将其计为重叠,但我的代码并没有满足我数据集中每个案例的目的。

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

【问题讨论】:

  • 请提供一个示例数据框,可能十行左右作为字典,所以它是可重现的df.to_dict('list')
  • 如果'time_a'和'time_b'在同一行,是否允许重叠?
  • @sammywemmy 嗨,原始数据框与示例结果相同,但只有前 4 列(即 .loc[:, 0:4]),结果仅添加信息它。
  • @Nev1111 嗯,你的意思是,对封闭区间使用逻辑条件,例如 '>=' 或 '

标签: python pandas dataframe datetime


【解决方案1】:

问题似乎归结为寻找重叠区间,其中区间由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

注意:我是 piso 的创造者。如果您有任何反馈或问题,请随时与我们联系。

【讨论】:

  • 这非常优雅和高效,显然我的元组解决方案效率不高,特别是对每一行和单行的整个搜索空间进行迭代。还有,我不知道这个 piso 库,我第一次听说它,现在我会研究它,谢谢你。如果我能回答这个问题,会给你更多的分数,谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-09-27
  • 1970-01-01
  • 2020-11-18
  • 1970-01-01
  • 2017-07-15
  • 1970-01-01
相关资源
最近更新 更多