【问题标题】:Merge overlapping datetime intervals合并重叠的日期时间间隔
【发布时间】:2021-03-28 09:54:02
【问题描述】:

我有一个包含多个日期时间间隔(开始时间、结束时间)和值的 df。

输入:

id   start          end            value
1    08:00:00.000   12:00:00.000   5
2    09:00:00.000   10:00:00.000   6
2    10:00:00.000   14:00:00.000   4
1    12:00:00.000   15:00:00.000   3

expected output:

id   start          end            value 
1    08:00:00.000   09:00:00.000   5
2    09:00:00.000   10:00:00.000   6
1    10:00:00.000   12:00:00.000   5
2    12:00:00.000   14:00:00.000   4
1    14:00:00.000   15:00:00.000   3

其中一些有重叠。目标是有连续的间隔而不重叠。

diagram

当有重叠时,我想保持最大值的区间。

我编写了一个在 df 上循环以查找重叠间隔、根据条件创建新的间隔序列并删除旧间隔的东西。 我想找到一种替代方法,更好地优化。也许在交叉点和之后分割所有间隔,在 df 上循环并根据条件删除重叠的间隔。

done = True

while done:
    done = False
    df_copy = df
    for i, row in df.iterrows():
        row_interval = pd.Interval(row.start, row.end)
        if done:
            break
        for j, row_copy in row_copy.iterrows():
            row_copy_interval = pd.Interval(row_copy.start, row_copy.end)
            if i is not j and row_interval.overlaps(row_copy_interval):
                earliest_start = np.minimum(row.start, row_copy.start)
                latest_start = np.maximum(row.start, row_copy.start)
                earliest_end = np.minimum(row.end, row_copy.end)
                latest_end = np.maximum(row.end, row_copy.end)

                if row.value > row_copy.value:
                    value = row.value
                else:
                    value = row_copy.value

                if row_interval == pd.Interval(earliest_start, earliest_end):
                    df = df.append('value': row.value, 'start': earliest_start,'end': latest_start}, ignore_index=True)
                    df = df.append('value': value, 'start': latest_start,'end': earliest_end}, ignore_index=True)
                    df = df.append('value': row_copy.value, 'start': earliest_end,'end': latest_end}, ignore_index=True)
                elif row_interval == pd.Interval(earliest_start, latest_end):
                    ...
                elif row_interval == pd.Interval(latest_start, latest_end):
                    ...
                elif row_interval == pd.Interval(latest_start, earliest_end):
                    ...

                df = df.drop([i, j]).drop_duplicates()
                done = True
                break

【问题讨论】:

  • 你想看看resampling
  • 我没有管理/理解如何将它应用到我的解决方案中,但这似乎很有趣。

标签: python pandas overlap overlapping


【解决方案1】:

我是portion 的维护者,这是一个 Python 库,用于处理任意(可比较)对象的(联合)区间(参见 https://github.com/AlexandreDecan/portion,也可在 PyPI 上获得)。

portion 提供的功能中,您会发现IntervalDict 类基本上充当经典字典,其中键是(联合)区间。此类在您的用例中可能会有所帮助,因为它允许您将所有日期(时间)间隔放入单个结构中并在其上应用一些逻辑。

一个IntervalDict 对象定义了一个.merge 函数,该函数接受另一个IntervalDict,并将一个函数作为输入来解释两个IntervalDict 实例必须如何合并。使用该函数,您可以指定必须为所有重叠间隔保留值的“最大值”。换句话说:为数据帧的每一行创建一个IntervalDict 实例,然后使用max 函数作为输入迭代地应用.merge,最后你会得到一个@987654332 的列表@ 对,其中每个 key 是一个(非重叠)间隔,每个 value 将是该日期(时间)值间隔内的最大值。

【讨论】:

    猜你喜欢
    • 2011-02-03
    • 2021-09-21
    • 1970-01-01
    • 1970-01-01
    • 2019-04-12
    • 2014-02-23
    • 2021-09-03
    • 2013-10-16
    相关资源
    最近更新 更多