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

计算索引日期与首次终止标识日期的天数差(无标识取末次观测)

问题

现有包含id、随访日期date、分组group、终止标识indicator(值为1代表终止)的DataFrame,需实现以下需求:

  • 对对应行填入索引日期(每个id+group组内的最早日期)与首次出现终止标识日期的天数差;
  • 若组内未出现终止标识,则填入索引日期至组内末次观测日期的天数;
  • 仅在终止发生的行(indicator=1)或无终止时的末次行填充该值,其余行填NA。

原始数据

id  date             group   indicator      
1   15-01-2022        1       0
1   15-01-2022        2       0
1   16-01-2022        2       1
1   20-01-2022        2       0
2   18-01-2022        1       0
2   20-01-2022        2       0
2   27-01-2022        2       0

期望结果

id  date             group   indicator     stoptime
1   15-01-2022        1       0             NA
1   15-01-2022        2       0             NA
1   16-01-2022        2       1             1
1   20-01-2022        2       0             NA
2   18-01-2022        1       0             NA
2   20-01-2022        2       0             NA
2   27-01-2022        2       0             9

解决方案

以下是基于Pandas的实现方案,核心逻辑是按id+group分组计算关键日期,再匹配填充目标列:

步骤1:数据预处理,转换日期格式

先将date列转为datetime类型,方便后续日期计算:

import pandas as pd

# 构造原始数据
df = pd.DataFrame({
    'id': [1,1,1,1,2,2,2],
    'date': ['15-01-2022','15-01-2022','16-01-2022','20-01-2022','18-01-2022','20-01-2022','27-01-2022'],
    'group': [1,2,2,2,1,2,2],
    'indicator': [0,0,1,0,0,0,0]
})

# 转换日期格式(适配日-月-年的输入格式)
df['date'] = pd.to_datetime(df['date'], format='%d-%m-%Y')

步骤2:按分组计算关键日期

按id和group分组,提取每组的三个核心日期:

# 分组计算索引日期、首次终止日期、末次观测日期
grouped_info = df.groupby(['id', 'group']).agg(
    index_date=('date', 'min'),
    first_stop_date=('date', lambda x: x[df.loc[x.index, 'indicator'] == 1].min()),
    last_date=('date', 'max')
).reset_index()

步骤3:合并数据并计算stoptime

将分组信息合并回原数据,根据规则填充stoptime:

# 合并分组信息到原DataFrame
df = df.merge(grouped_info, on=['id', 'group'], how='left')

# 初始化stoptime列为NA
df['stoptime'] = pd.NA

# 填充终止行的天数差:首次终止日期 - 索引日期
stop_row_mask = df['indicator'] == 1
df.loc[stop_row_mask, 'stoptime'] = (df.loc[stop_row_mask, 'first_stop_date'] - df.loc[stop_row_mask, 'index_date']).dt.days

# 标记每个分组的末次行
df['is_group_last'] = df.groupby(['id', 'group'])['date'].rank(ascending=False, method='first') == 1

# 填充无终止组的末次行天数差:末次观测日期 - 索引日期
no_stop_last_mask = df['first_stop_date'].isna() & df['is_group_last']
df.loc[no_stop_last_mask, 'stoptime'] = (df.loc[no_stop_last_mask, 'last_date'] - df.loc[no_stop_last_mask, 'index_date']).dt.days

# 清理临时辅助列
df = df.drop(columns=['index_date', 'first_stop_date', 'last_date', 'is_group_last'])

# 输出结果
print(df.to_string(index=False))

运行结果

输出与期望结果一致:

id       date  group  indicator  stoptime
 1 2022-01-15      1          0       <NA>
 1 2022-01-15      2          0       <NA>
 1 2022-01-16      2          1         1
 1 2022-01-20      2          0       <NA>
 2 2022-01-18      1          0       <NA>
 2 2022-01-20      2          0       <NA>
 2 2022-01-27      2          0         9

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 22:10:28