You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在DataFrame中用无重叠区间替换重叠区间?

清理DataFrame中的重叠时间区间(高效方案)

问题描述

需要清理一个包含时间区间的DataFrame,消除所有重叠区间。原始DataFrame结构如下:

start    end     speaker
0   0.03   0.33  SPEAKER_02
1   1.24   6.91  SPEAKER_02
2   1.38   2.03  SPEAKER_00
3   7.11   9.64  SPEAKER_02
4   9.80  21.02  SPEAKER_02
5  15.37  15.52  SPEAKER_01
6  16.55  16.80  SPEAKER_00
7  21.36  26.40  SPEAKER_02
8  26.76  27.01  SPEAKER_02

重叠处理规则:当区间重叠时,拆分出无重叠的新行,子区间(完全包含在长区间内的区间)的speaker优先覆盖长区间的对应部分。例如:

  • 原第1、2行需拆分为3行无重叠区间:
    1   1.24   1.37  SPEAKER_02
    2   1.38   2.03  SPEAKER_00
    3   2.04   6.91  SPEAKER_02
    
  • 原第4、5、6行需拆分为4行无重叠区间:
    4   9.80  15.36  SPEAKER_02
    5  15.37  15.52  SPEAKER_01
    6  15.53  16.54  SPEAKER_02
    7  16.55  16.80  SPEAKER_00
    

核心要求:数据量极大,方案必须高效,避免低效的自定义循环。

高效解决方案

采用事件驱动+栈维护的方法,时间复杂度为O(n log n),适合大数据量处理:

import pandas as pd

# 初始化原始DataFrame
df = pd.DataFrame({
    'start': [0.03, 1.24, 1.38, 7.11, 9.80, 15.37, 16.55, 21.36, 26.76],
    'end': [0.33, 6.91, 2.03, 9.64, 21.02, 15.52, 16.80, 26.40, 27.01],
    'speaker': ['SPEAKER_02', 'SPEAKER_02', 'SPEAKER_00', 'SPEAKER_02', 'SPEAKER_02', 'SPEAKER_01', 'SPEAKER_00', 'SPEAKER_02', 'SPEAKER_02']
})

# 生成事件列表:(时间, 事件类型, speaker)
# enter表示进入区间,exit表示离开区间(离开时间设为end+0.01,确保区间无重叠)
events = []
for _, row in df.iterrows():
    events.append((row['start'], 'enter', row['speaker']))
    events.append((row['end'] + 0.01, 'exit', row['speaker']))

# 排序事件:按时间升序,同时间时exit事件优先(避免同一时间点的重叠)
events.sort(key=lambda x: (x[0], 0 if x[1] == 'exit' else 1))

# 遍历事件生成无重叠区间
result = []
current_time = None
speaker_stack = []
current_speaker = None

for time, event_type, speaker in events:
    # 生成当前时间到事件时间的区间(如果有间隔)
    if current_time is not None and time > current_time:
        result.append({
            'start': round(current_time, 2),
            'end': round(time - 0.01, 2),
            'speaker': current_speaker
        })
    # 更新speaker栈
    if event_type == 'enter':
        speaker_stack.append(speaker)
        current_speaker = speaker_stack[-1]
    else:
        # 弹出对应的speaker,处理嵌套场景
        try:
            speaker_stack.remove(speaker)
        except ValueError:
            pass
        current_speaker = speaker_stack[-1] if speaker_stack else None
    current_time = time

# 转换为结果DataFrame
result_df = pd.DataFrame(result)
print(result_df)

方案说明

  1. 事件生成:将每个区间拆分为「进入」和「离开」两个事件,离开时间设为原区间end+0.01,保证区间左闭右闭且无重叠。
  2. 事件排序:按时间排序,同时间的离开事件优先,避免出现同一时间点先进入后离开导致的逻辑错误。
  3. 栈维护speaker:用栈记录当前活跃的speaker,子区间的进入事件会压入栈顶,优先使用;离开事件弹出对应speaker,自动恢复到父区间的speaker。
  4. 区间生成:遍历事件时,根据相邻事件的时间差生成无重叠的区间,确保覆盖所有原始时间范围。

内容的提问来源于stack exchange,提问作者cory Jackson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 11:12:33