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

如何在Pandas中基于values_1筛选存在时间重叠的行

解决Pandas按分组筛选时间重叠行的问题

需求说明

基于values_1列分组,仅保留同一分组内Start DateTime与End DateTime存在时间重叠的行;无重叠的分组直接移除,分组内无重叠的行也剔除。

实现方案

以下提供两种实现方式,分别适配小数据量和大数据量场景:

1. 基础循环实现(适合小数据量)

先构造示例DataFrame并确保时间列为datetime类型,再通过分组遍历判断重叠:

import pandas as pd

# 构造示例数据
data = {
    'values_1': ['VGM', 'VGM', 'VGM', 'WEH', 'WEH', 'WEH', 'POH', 'POH'],
    'uniqId': [1278, 1259, 2567, 9854, 9124, 9785, 3479, 3449],
    'DeptId': ['BKNG', 'BKNG', 'BKNG', 'ASKG', 'ASKG', 'ASKG', 'ASKG', 'ASKG'],
    'Start DateTime': ['2023-09-05 18:35:28', '2023-09-05 18:55:18', '2023-09-05 14:29:38',
                       '2023-09-05 13:45:58', '2023-09-05 17:25:28', '2023-09-05 16:15:21',
                       '2023-09-05 15:35:29', '2023-09-05 17:35:28'],
    'End DateTime': ['2023-09-05 20:05:28', '2023-09-05 19:25:38', '2023-09-05 17:35:28',
                     '2023-09-05 15:00:00', '2023-09-05 19:43:13', '2023-09-05 18:24:02',
                     '2023-09-05 17:25:22', '2023-09-05 18:35:19']
}

df = pd.DataFrame(data)

# 转换时间列为datetime类型(若未转换)
df['Start DateTime'] = pd.to_datetime(df['Start DateTime'])
df['End DateTime'] = pd.to_datetime(df['End DateTime'])

def filter_overlapping(group):
    overlaps = []
    for idx, row in group.iterrows():
        # 计算当前行与组内所有行的重叠情况
        mask = (group['Start DateTime'] < row['End DateTime']) & (group['End DateTime'] > row['Start DateTime'])
        # 排除自身,至少有一个其他行重叠则保留
        has_overlap = mask.sum() > 1
        overlaps.append(has_overlap)
    group['has_overlap'] = overlaps
    return group[group['has_overlap']]

# 分组筛选并合并结果
result = df.groupby('values_1', group_keys=False).apply(filter_overlapping).drop('has_overlap', axis=1)
print(result)

2. 向量化优化实现(适合大数据量)

利用Pandas的向量化操作替代循环,大幅提升处理效率:

def filter_overlapping_vectorized(group):
    # 生成时间矩阵,计算所有行对的重叠关系
    starts = group['Start DateTime'].values[:, None]
    ends = group['End DateTime'].values[:, None]
    # 重叠条件:A的开始 < B的结束 且 B的开始 < A的结束
    overlap_matrix = (starts < ends.T) & (starts.T < ends)
    # 每行是否有至少一个非自身的重叠行
    has_overlap = overlap_matrix.sum(axis=1) > 1
    return group[has_overlap]

# 分组应用向量化筛选
result = df.groupby('values_1', group_keys=False).apply(filter_overlapping_vectorized)
print(result)

输出结果

两种方式都会得到符合预期的DataFrame:

values_1uniqIdDeptIdStart DateTimeEnd DateTime
VGM1278BKNG2023-09-05 18:35:282023-09-05 20:05:28
VGM1259BKNG2023-09-05 18:55:182023-09-05 19:25:38
WEH9124ASKG2023-09-05 17:25:282023-09-05 19:43:13
WEH9785ASKG2023-09-05 16:15:212023-09-05 18:24:02

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 16:44:51