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

分组计算每行距离上次incident发生的天数(Pandas)

问题描述

现有如下DataFrame:

customer_idstart_dateend_dateincident
12022-01-012022-01-03False
12022-01-022022-01-04True
12022-01-042022-01-06False
12022-01-052022-01-08False
12022-01-052022-01-06False

需要按customer_id分组,为每行计算距离上次incident(值为True)发生的天数:用当前行的start_date减去最后一行incident等于True的end_date,得到间隔天数。

期望输出:

customer_idstart_dateend_dateincidentdays_since_last_incident
12022-01-012022-01-03FalseNaN
12022-01-022022-01-04TrueNaN
12022-01-042022-01-06False0
12022-01-052022-01-08False1
12022-01-052022-01-06False1

当前尝试用apply函数处理,但无前置incident的行出现越界错误,仅对存在前置incident的行有效,代码如下:

def days_since_last_incident(group):
    group["days_since_last_incidents"] = group.apply(
        lambda row: (
            row["start_date"]
            - (
                group[
                    (group["incident"] == True)
                    & (group["end_date"] <= row["start_date"])
                ]["end_date"].values
            )
        ).days,
        axis=1,
    )


df.groupby("customer_id").apply(days_since_last_incident)
优雅实现方案

可以利用pandas的分组、填充和日期矢量化运算实现,避免逐行apply的低效和越界问题:

代码实现

import pandas as pd

# 转换日期列为datetime类型(如果原始数据是字符串格式)
df['start_date'] = pd.to_datetime(df['start_date'])
df['end_date'] = pd.to_datetime(df['end_date'])

# 分组提取最近一次incident的end_date并向前填充
df['last_incident_end'] = df.groupby('customer_id').apply(
    lambda g: g['end_date'].where(g['incident']).ffill()
).reset_index(level=0, drop=True)

# 计算天数间隔
df['days_since_last_incident'] = (df['start_date'] - df['last_incident_end']).dt.days

# 为incident=True的行和无前置incident的行设置NaN
mask = df['incident'] | df['last_incident_end'].isna()
df.loc[mask, 'days_since_last_incident'] = pd.NA

# 删除辅助列(可选)
df = df.drop('last_incident_end', axis=1)

print(df)

代码说明

  1. 日期类型转换:确保日期列是datetime格式,才能进行后续运算
  2. 提取并填充最近incident日期:
    • g['end_date'].where(g['incident']):仅保留incident为True的行的end_date,其余行设为NaN
    • ffill():向前填充NaN,让每一行自动继承最近一次incident的end_date
  3. 天数计算:直接用日期列做差后提取天数,全程矢量化操作,效率远高于逐行apply
  4. NaN值处理:通过掩码把incident本身为True的行、以及没有前置incident的行的结果设为NaN,完全匹配需求

输出结果

运行后将得到与期望完全一致的DataFrame。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 23:55:31