基于日期阈值的Pandas DataFrame分组累计增量列实现问题
Pandas按组生成累计间隔标识列diff_weeks
原始DataFrame
| num_ID | start_date | end_date | other_column |
|---|---|---|---|
| 1 | 2022-02-14 | 2022-02-15 | 09:23:00 |
| 1 | 2022-02-20 | 2022-02-25 | 12:10:01 |
| 2 | 2022-03-11 | 2022-03-21 | 08:21:00 |
| 2 | 2022-03-22 | 2022-03-27 | 02:36:00 |
| 2 | 2022-04-10 | 2022-04-15 | 11:43:03 |
| 3 | 2022-02-04 | 2022-02-06 | 16:51:00 |
| 3 | 2022-02-14 | 2022-02-23 | 19:35:10 |
| 3 | 2022-03-05 | 2022-03-06 | 21:05:13 |
| 4 | 2022-02-28 | 2022-10-12 | 00:01:00 |
需求说明
按num_ID分组新增diff_weeks列:
- 每组首行值为0
- 其余行:若同组前一行的
end_date与当前行start_date间隔≥7天,则diff_weeks= 前一行值 +1;否则保持前一行值
预期结果
| num_ID | start_date | end_date | other_column | diff_weeks |
|---|---|---|---|---|
| 1 | 2022-02-14 | 2022-02-15 | 09:23:00 | 0 |
| 1 | 2022-02-20 | 2022-02-25 | 12:10:01 | 0 |
| 2 | 2022-03-11 | 2022-03-21 | 08:21:00 | 0 |
| 2 | 2022-03-22 | 2022-03-27 | 02:36:00 | 0 |
| 2 | 2022-04-10 | 2022-04-15 | 11:43:03 | 1 |
| 3 | 2022-02-04 | 2022-02-06 | 16:51:00 | 0 |
| 3 | 2022-02-14 | 2022-02-23 | 19:35:10 | 1 |
| 3 | 2022-03-05 | 2022-03-06 | 21:05:13 | 2 |
| 4 | 2022-02-28 | 2022-10-12 | 00:01:00 | 0 |
原代码问题
使用以下代码时,既未实现累计求和逻辑,还抛出TypeError: unsupported operand type(s) for -: 'datetime.date' and 'float'错误:
df['diff_weeks'] = (df['start_date'].sub(df.groupby('num_ID')['end_date'].shift()) .ge('7d').astype(int) )
错误原因:
- 分组shift后每组首行产生float类型的NaN,导致日期与float类型相减报错
- 仅生成了0/1的间隔标识列,未实现“满足条件累计加1”的需求
正确实现方案
步骤1:确保日期列类型正确
先将start_date和end_date转换为datetime类型(若原始数据还不是):
import pandas as pd df['start_date'] = pd.to_datetime(df['start_date']) df['end_date'] = pd.to_datetime(df['end_date'])
步骤2:生成累计间隔标识列
通过分组计算日期差、生成间隔标识,再按组累计求和:
# 计算间隔标识并按组累计求和 df['diff_weeks'] = ( (df['start_date'] - df.groupby('num_ID')['end_date'].shift()).dt.days >= 7 ).astype(int).groupby(df['num_ID']).cumsum()
代码解释
df.groupby('num_ID')['end_date'].shift():按组将end_date下移一行,每组首行得到NaN(df['start_date'] - ...).dt.days >=7:计算当前行start_date与前一行end_date的天数差,判断是否≥7,生成布尔值astype(int):将布尔值转为0/1(False→0,True→1)groupby(df['num_ID']).cumsum():按组对0/1序列累计求和,自动实现“满足条件加1,否则保持原值”的逻辑;每组首行的NaN经过cumsum后自动变为0,符合需求
内容的提问来源于stack exchange,提问作者Carola
相关产品推荐
相关产品推荐

