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

基于滚动时间窗口的Pandas值重现检测问题求助

解决按分组时间窗口检查值前后出现的问题

我来帮你搞定这个需求!先明确一下我们要实现的目标:按ColN字段分组,针对每一行,检查它的ColN_ext值是否在当前日期前后5天的滚动窗口内的其他行中出现(区分前后),最终生成符合预期的flag列。

首先,先把你提供的初始DataFrame代码放出来,方便我们复现环境:

import pandas as pd 
import numpy as np 

df = pd.DataFrame() 
df['ColN']=['AAA', 'AAA', 'AAA', 'AAA', 'ABC'] 
df['ColN_dt']=['03-01-2018', '03-04-2018', '03-05-2018', '03-08-2018', '03-12-2018'] 
df['ColN_ext']=['A', 'B', 'B', 'B', 'B'] 
df['ColN_dt'] = pd.to_datetime(df['ColN_dt'])

需求拆解

先对应预期的flag结果[NaN, 0, 1, NaN, NaN]拆解规则:

  • 第1行(AAA组,2018-03-01,ext=A):窗口内只有后续行,且没有A,保持NaN;
  • 第2行(AAA组,2018-03-04,ext=B):窗口内后续有B,但前序没有,所以flag=0;
  • 第3行(AAA组,2018-03-05,ext=B):窗口内前序和后续都有B,所以flag=1;
  • 第4行(AAA组,2018-03-08,ext=B):窗口内只有前序有B,后续无数据,保持NaN;
  • 第5行(ABC组,仅一行):窗口内无其他行,保持NaN。

解决方案代码

下面是实现这个逻辑的代码,注释已经写得很清楚了:

# 先按ColN分组,确保每个组内按日期排序(原数据已经有序,但加这一步更稳妥)
df = df.sort_values(['ColN', 'ColN_dt']).reset_index(drop=True)

def check_ext_in_window(group):
    # 初始化flag列为NaN
    group['flag'] = np.nan
    total_rows = len(group)
    
    for idx in range(total_rows):
        current_ext = group['ColN_ext'].iloc[idx]
        current_date = group['ColN_dt'].iloc[idx]
        
        # 计算窗口的时间范围:当前日期前后5天
        window_start = current_date - pd.Timedelta(days=5)
        window_end = current_date + pd.Timedelta(days=5)
        
        # 筛选窗口内除当前行外的所有数据
        window_data = group[
            (group['ColN_dt'] >= window_start) &
            (group['ColN_dt'] <= window_end) &
            (group.index != idx)
        ]
        
        # 窗口内没有其他数据,直接跳过
        if len(window_data) == 0:
            continue
        
        # 检查当前ext是否在窗口内的前序行(日期早于当前)存在
        has_before = any(window_data[window_data['ColN_dt'] < current_date]['ColN_ext'] == current_ext)
        # 检查当前ext是否在窗口内的后序行(日期晚于当前)存在
        has_after = any(window_data[window_data['ColN_dt'] > current_date]['ColN_ext'] == current_ext)
        
        # 根据检查结果设置flag值
        if has_before and has_after:
            group['flag'].iloc[idx] = 1
        elif has_before or has_after:
            group['flag'].iloc[idx] = 0
    
    return group

# 把函数应用到每个分组
df = df.groupby('ColN', group_keys=False).apply(check_ext_in_window)

# 查看结果
print(df['flag'].tolist())
# 输出:[nan, 0.0, 1.0, nan, nan]

代码说明

  1. 排序分组:确保每个组内的数据是按日期顺序排列的,避免窗口计算出错;
  2. 窗口范围计算:用pd.Timedelta来定义前后5天的时间窗口,比固定行数的滚动窗口更贴合你的需求(因为日期可能不连续);
  3. 前后存在性检查:分别判断当前ColN_ext在窗口内的前序和后序行中是否存在,再根据组合结果设置flag;
  4. 边界处理:如果窗口内没有其他数据,保持flag为NaN,符合预期。

如果你的数据集很大,遍历的方式可能效率不够高,可以考虑预计算每个组的ColN_ext和日期的映射关系来优化,但对于一般规模的数据,这个方法已经足够清晰好用了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:02:29