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

Python如何识别同姓名同日期下冲突≥3次的并发事件

并发事件识别实现方案

核心逻辑

基于pandas向量化运算实现,完全替代循环处理,性能远高于逐行遍历,适配你的规则:同一姓名、同一事件日期下,连续冲突次数≥3判定为并发。
处理流程如下:

  • 按「姓名+事件日期」分组,组内所有事件按开始时间升序排序
  • 生成冲突标记列:判断当前行与前一行时间是否重叠,重叠则标记为冲突
  • 为连续冲突的事件段打统一分组标记,所有连续冲突的行会归属同一个分组
  • 统计每个冲突分组的长度,长度≥3的分组标记为并发事件组,回写标记到原数据

完整可运行代码

import pandas as pd

# ---------------------- 示例数据构造,可替换为你的实际数据 ----------------------
df = pd.DataFrame({
    "姓名": ["张三", "张三", "张三", "张三", "李四", "李四", "李四", "李四"],
    "事件日期": ["2024-05-01", "2024-05-01", "2024-05-01", "2024-05-02", "2024-05-01", "2024-05-01", "2024-05-01", "2024-05-01"],
    "开始时间": ["09:00", "09:30", "10:00", "09:00", "08:00", "08:20", "08:40", "09:10"],
    "结束时间": ["10:00", "10:30", "11:00", "10:00", "09:00", "08:50", "09:20", "09:40"]
})
# 时间列转datetime格式,方便比较
df["开始时间"] = pd.to_datetime(df["事件日期"] + " " + df["开始时间"])
df["结束时间"] = pd.to_datetime(df["事件日期"] + " " + df["结束时间"])

# ---------------------- 核心处理逻辑 ----------------------
# 1. 按分组排序,保证时间序列有序
df = df.sort_values(by=["姓名", "事件日期", "开始时间"]).reset_index(drop=True)

# 2. 生成逐行冲突标记:当前行开始时间 < 上一行结束时间,即为和上一行冲突
df["is_conflict"] = df.groupby(["姓名", "事件日期"])["开始时间"].shift(1) < df["结束时间"]
# 每组第一行无前置行,默认无冲突
df.loc[df.groupby(["姓名", "事件日期"]).head(1).index, "is_conflict"] = False

# 3. 为连续冲突段打分组标记
df["conflict_group"] = df.groupby(["姓名", "事件日期"])["is_conflict"].apply(
    lambda x: (x != x.shift()).cumsum()
)

# 4. 筛选满足连续冲突≥3的分组
group_stat = df.groupby(["姓名", "事件日期", "conflict_group", "is_conflict"]).size().reset_index(name="conflict_cnt")
# 此处conflict_cnt即为连续冲突次数,按需调整阈值即可
target_groups = group_stat[(group_stat["is_conflict"] == True) & (group_stat["conflict_cnt"] >= 3)]

# 5. 回写并发标记到原表
df["is_concurrent"] = df.set_index(["姓名", "事件日期", "conflict_group"]).index.isin(
    target_groups.set_index(["姓名", "事件日期", "conflict_group"]).index
)

# 可选:删除中间过程列
df = df.drop(columns=["is_conflict", "conflict_group"])

备选实现(非连续冲突场景)

如果规则不需要冲突连续,只要同一个人同一天内和当前事件冲突的事件总数≥3就算并发,可直接用区间重叠统计实现:

# 构造时间区间
df["time_interval"] = df.apply(lambda x: pd.Interval(x["开始时间"], x["结束时间"], closed="left"), axis=1)

# 统计每个区间的重叠次数
def calc_overlap_count(interval_list):
    return [sum(iv.overlaps(current_iv) for iv in interval_list) for current_iv in interval_list]

df["overlap_count"] = df.groupby(["姓名", "事件日期"])["time_interval"].transform(calc_overlap_count)

# 标记并发
df["is_concurrent"] = df["overlap_count"] >= 3

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 13:24:04