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

Apache Spark Scala:如何检测时间区间交集并进行分组?

解决时间区间分组问题

核心逻辑:判断两个时间区间是否有交集

两个时间区间 [s1, e1] 和 [s2, e2] 存在交集的充要条件是:
s1 < e2 且 s2 < e1

简单解释:只要一个区间的开始时间早于另一个区间的结束时间,且另一个区间的开始时间也早于这个区间的结束时间,就说明两个区间有重叠或相交部分。

实现步骤(处理无序数据)

因为数据是随机排序的,直接逐个判断效率低,推荐先排序再用贪心算法合并重叠区间,最后给原始数据分配组号。

1. 准备数据并确保日期类型

首先将start和end列转换为datetime类型(如果尚未转换):

import pandas as pd

# 构造示例数据
data = {
    'start': ['2019-07-01 10:01:19.000', '2019-07-01 10:10:05.000', '2019-07-01 10:35:00.000',
              '2019-07-01 15:20:00.000', '2019-07-01 16:10:00.000', '2019-07-01 16:30:00.000'],
    'end': ['2019-07-01 10:11:00.000', '2019-07-01 10:40:00.000', '2019-07-01 12:30:00.000',
            '2019-07-01 15:50:00.000', '2019-07-01 16:35:00.000', '2019-07-01 17:00:00.000']
}

df = pd.DataFrame(data)
# 转换为datetime类型
df['start'] = pd.to_datetime(df['start'])
df['end'] = pd.to_datetime(df['end'])

2. 排序并合并重叠区间

先按start列排序,然后遍历合并所有相交或重叠的区间,记录每个组的范围:

# 按start排序,方便后续合并
sorted_df = df.sort_values('start').reset_index(drop=True)

# 初始化合并后的区间列表,每个元素包含组号、组的起始和结束时间
merged_groups = []
for idx, row in sorted_df.iterrows():
    if not merged_groups:
        # 第一个区间直接作为第一组
        merged_groups.append({'group': 1, 'group_start': row['start'], 'group_end': row['end']})
    else:
        last_group = merged_groups[-1]
        # 判断当前区间和最后一个合并组是否有交集
        if row['start'] < last_group['group_end']:
            # 有交集,合并组的结束时间为两者的最大值
            last_group['group_end'] = max(last_group['group_end'], row['end'])
        else:
            # 无交集,新增一个组
            merged_groups.append({
                'group': len(merged_groups) + 1,
                'group_start': row['start'],
                'group_end': row['end']
            })

3. 给原始数据分配组号

遍历原始数据的每个区间,判断它属于哪个合并后的组:

def assign_group(row):
    for group_info in merged_groups:
        # 判断当前区间和组区间是否有交集
        if row['start'] < group_info['group_end'] and group_info['group_start'] < row['end']:
            return group_info['group']
    # 理论上不会走到这里,除非有完全独立的新区间
    return len(merged_groups) + 1

# 新增group列
df['group'] = df.apply(assign_group, axis=1)

最终结果

运行上述代码后,你的DataFrame会生成group列,结果和你期望的一致:

startendgroup
2019-07-01 10:01:19.0002019-07-01 10:11:00.0001
2019-07-01 10:10:05.0002019-07-01 10:40:00.0001
2019-07-01 10:35:00.0002019-07-01 12:30:00.0001
2019-07-01 15:20:00.0002019-07-01 15:50:00.0002
2019-07-01 16:10:00.0002019-07-01 16:35:00.0003
2019-07-01 16:30:00.0002019-07-01 17:00:00.0003

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 23:40:38