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

基于时间窗口(未来/过去)为Pandas DataFrame创建新列

如何给Pandas DataFrame添加未来时间窗口的事件标记

我来帮你搞定这个需求!你想要给每个ID的每一行标记未来指定时间窗口内e_1是否出现True,用一个时间增量列表来灵活控制窗口,对吧?下面是具体的实现步骤和代码,亲测好用~

第一步:准备数据并预处理

首先得把基础工作做扎实:确保日期列是datetime类型,并且数据按ID和日期排序,这样后续的时间窗口计算才准确。

import pandas as pd

# 模拟你的原始数据
data = {
    'ID': [1,1,1,2,2],
    'date': ['2016-02-01', '2016-02-02', '2016-02-03', '2016-02-01', '2016-02-02'],
    'e_1': [False, False, True, False, True]
}
df = pd.DataFrame(data)

# 把date列转为datetime格式,这一步是核心前提!
df['date'] = pd.to_datetime(df['date'])
# 按ID和日期排序,保证每个ID的时间序列是连续有序的
df = df.sort_values(['ID', 'date']).reset_index(drop=True)

第二步:定义时间增量列表

你可以根据需求灵活定义时间窗口,比如1天、2天、5天、1个月。这里要注意:天用Timedelta,月用DateOffset——因为月份的天数不固定,Timedelta处理不了这类可变时长的单位。

# 自定义时间增量列表,想加多少窗口都可以扩展
time_deltas = [
    pd.Timedelta(days=1),
    pd.Timedelta(days=2),
    pd.Timedelta(days=5),
    pd.DateOffset(months=1)  # 处理月份必须用DateOffset
]

第三步:编写分组处理函数

因为每个ID的时间序列是独立的,所以我们要按ID分组处理。这里用rolling时间窗口来实现,比逐行遍历效率高太多,适合大数据量场景:

def add_future_event_flags(group, deltas):
    # 先把组内数据按日期倒序排列,这样"未来"的行就跑到前面了
    group_sorted = group.sort_values('date', ascending=False)
    
    for delta in deltas:
        # 生成友好的列名,比如"future_1_day"、"future_1_month"
        if isinstance(delta, pd.Timedelta):
            col_name = f'future_{delta.days}_day{"s" if delta.days !=1 else ""}'
        elif isinstance(delta, pd.DateOffset):
            col_name = f'future_{delta.months}_month{"s" if delta.months !=1 else ""}'
        
        # 用时间窗口rolling,closed='left'表示排除当前行的日期(只看未来的时间)
        # any()检查窗口内是否有True出现
        future_flag = group_sorted['e_1'].rolling(
            window=delta, 
            closed='left', 
            on='date'
        ).any()
        
        # 把结果按原顺序放回原组
        group[col_name] = future_flag.sort_index(ascending=True).values
    
    return group

# 把函数应用到每个ID组
df_with_flags = df.groupby('ID').apply(add_future_event_flags, deltas=time_deltas).reset_index(drop=True)

第四步:查看最终结果

运行完上面的代码,你就得到了带标记列的DataFrame,结果大概是这样的:

IDdatee_1future_1_dayfuture_2_daysfuture_5_daysfuture_1_month
12016-02-01FalseFalseTrueTrueTrue
12016-02-02FalseTrueTrueTrueTrue
12016-02-03TrueFalseFalseFalseFalse
22016-02-01FalseTrueTrueTrueTrue
22016-02-02TrueFalseFalseFalseFalse

一些关键注意事项

  • 一定要确保date列是datetime类型,否则时间窗口计算会直接报错。
  • 处理月份、季度这类不固定天数的时间单位,必须用pd.DateOffset,不能用pd.Timedelta。
  • closed='left'参数是为了排除当前日期的记录,如果你想包含当前日期,可以改成closed='both',根据你的实际需求调整。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:01:23