如何使用Pandas计算分组内距离上一次指定事件发生的天数
Pandas 实现方案
核心思路是通过分组+向前填充的方式定位每个学生最近一次不及格的考试日期,再直接计算日期间隔,全程使用Pandas向量化操作,性能远高于常规循环。
前置处理
首先需要将字符串格式的考试日期转为Pandas datetime类型,用于后续日期计算:
import pandas as pd # 示例数据初始化 df = pd.DataFrame({'StudentName': ['Anil','Ramu','Ramu','Anil','Peter','Peter','Anil','Ramu','Peter','Anil'], 'ExamDate': ['2021-01-10','2021-01-20','2021-02-22','2021-03-30','2021-01-04','2021-06-06','2021-04-30','2021-07-30','2021-07-08','2021-09-07'], 'Result': ['Fail','Pass','Fail','Pass','Pass','Pass','Pass','Pass','Fail','Pass']}) # 转换日期格式 df['ExamDate'] = pd.to_datetime(df['ExamDate'])
核心计算步骤
- 新建临时列存储不及格记录的考试日期,非不及格记录行留空
- 按学生姓名分组,向前填充临时列,使每个学生的所有行都能匹配到最近一次不及格的考试日期,无不及格历史的行留空
- 计算当前考试日期与最近一次不及格日期的天数差,处理特殊情况:无不及格历史、当前行本身是不及格的记录,值统一设为0
- 清理临时列
对应代码:
# 标记所有不及格记录的考试日期 df['last_fail_date'] = df.loc[df['Result'] == 'Fail', 'ExamDate'] # 按学生分组,向前填充最近一次不及格日期 df['last_fail_date'] = df.groupby('StudentName')['last_fail_date'].ffill() # 计算天数差,处理特殊情况 df['LastFailedDays'] = (df['ExamDate'] - df['last_fail_date']).dt.days.fillna(0).astype(int) df.loc[df['Result'] == 'Fail', 'LastFailedDays'] = 0 # 删除临时列 df = df.drop(columns='last_fail_date')
输出结果验证
运行后输出的df与预期结果完全一致:
StudentName ExamDate Result LastFailedDays 0 Anil 2021-01-10 Fail 0 1 Ramu 2021-01-20 Pass 0 2 Ramu 2021-02-22 Fail 0 3 Anil 2021-03-30 Pass 79 4 Peter 2021-01-04 Pass 0 5 Peter 2021-06-06 Pass 0 6 Anil 2021-04-30 Pass 110 7 Ramu 2021-07-30 Pass 158 8 Peter 2021-07-08 Fail 0 9 Anil 2021-09-07 Pass 240
内容的提问来源于stack exchange,提问作者Amey Kumar Samala
相关产品推荐
相关产品推荐

