在python

时间:2018-02-12 14:14:59

标签: python pandas datetime overlap

我试图检查同一个file_id中的两个时间段(由其持续时间表示为time_from和time_to)是否在以下数据帧中重叠:

df1
    id,file_id,time_from,time_to
    1,10,00:00:19,00:00:25
    2,12,00:02:39,00:02:49
    3,12,00:04:18,00:04:30
    4,12,00:05:30,00:05:55
    5,15,00:01:35,00:01:38
    6,18,00:07:35,00:07:48


df2 
    id,file_id,time_from,time_to
    1,10,00:00:18,00:00:26
    2,12,00:02:30,00:02:49
    3,12,00:05:28,00:05:56
    4,15,00:01:40,00:01:50

基本上我想计算相同file_id的两个数据帧中段重叠的次数,允许time_from和time_to之间的给定程度的距离(比如+/- 4秒)。

输出应该是这样的:

file_id, number_of_overlapping_segments
10, 1
12, 2
15, 1
18, 0

这是唯一一种情况,即两个时间段不重叠且算法应返回0(假设距离> 4秒)。其他所有情况都应该返回1:

               [_____]

   [________]           [______]

到目前为止,我的方法是使用pandas将时间值延长4秒左右(限制) 给定的时间段并创建保存具有重叠时间段的行的临时数据帧。 例如:

import pandas as pd

left_overlap = []
right_overlap = []

for f in list(set(df1.file_id) & set(df2.file_id)):
    for t_from, t_from_lim in list(zip(df2[df2.file_id==f]['time_from'],
                                       df1[df1file_id==f]['time_from_limit'])):
        if t_from > t_from_lim:
            left_overlap.append(df_2[(df2.file_id==audio) & \
                                             (df2.time_from==t_from)])

df_left_overlap = pd.concat(left_overlap).reset_index(drop=True)


for f in list(set(df1.file_id) & set(df2.file_id)):
    for t_to, t_to_lim in list(zip(df_left_overlap[df_left_overlap.file_id==f]['time_to'],
                                       df1[df1.file_id==f]['time_to_limit'])):
        if t_to < t_to_lim:
            right_overlap.append(
                df_left_overlap[(df_left_overlap.file_id==f) & \
                                    (df_left_overlap.time_to==t_to)])

overlap = pd.concat(right_overlap)

我认为这个解决方案并不高效,我希望找到一种更强大的方法。

提前致谢!

1 个答案:

答案 0 :(得分:1)

看起来您正在添加time_from-(4秒)和time_to +(4秒)的属性。 (这就是time_from_limit和time_to_limit是什么?)看起来你似乎正在尝试检测重叠,当它实际上更容易测试它们是否不重叠,并否定它。

例如(伪代码):

for segment1 in df1:
    for segment2 in df2 records with matching fileid:
        if not (segment1.['time_from'] >= segment2.['time_to'] + (4 seconds) or
                segment2.['time_from'] >= segment1.['time_to'] + (4 seconds)):
        # They overlap
        counters[fileid]++