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

Pandas相同id分组下合并带NaT的连续日期且特征值一致的行

解决方案

核心思路:通过给同ID、同特征的连续日期打分组标签,再聚合得到合并结果,兼容End列NaT场景。

首先给出完整可运行代码:

import pandas as pd
import numpy as np

# 构造测试数据,你可以替换成自己的数据集读取逻辑
df = pd.DataFrame({
    'Id': ['A', 'A', 'A', 'A', 'B', 'B'],
    'Start': pd.to_datetime(['2020-01-01', '2020-01-16', '2020-01-31', '2020-07-01', '2020-01-31', '2020-02-16']),
    'End': pd.to_datetime(['2020-01-15', '2020-01-30', '2020-02-15', '2020-07-15', '2020-02-15', pd.NaT]),
    'Feature1': [1, 1, 0, 0, 0, 0],
    'Feature2': [1, 1, 1, 1, 0, 0]
})

# 1. 先按Id、特征列、Start排序,保证日期顺序正确
df_sorted = df.sort_values(by=['Id', 'Feature1', 'Feature2', 'Start']).reset_index(drop=True)

# 2. 标记新分组:同ID同特征下,当前行和上一行日期不连续就算新分组
# 连续判断规则:上一行的End +1天 == 当前行的Start
df_sorted['is_new_group'] = df_sorted.groupby(['Id', 'Feature1', 'Feature2']).apply(
    lambda x: ~(x['End'].shift(1) + pd.Timedelta(days=1) == x['Start'])
).reset_index(drop=True)

# 3. 生成连续块的唯一分组标记
df_sorted['block_id'] = df_sorted['is_new_group'].cumsum()

# 4. 聚合合并,End列特殊处理:组内存在NaT则返回NaT,否则返回组内最大日期
def agg_end(s):
    if s.isna().any():
        return pd.NaT
    return s.max()

result = df_sorted.groupby(['Id', 'Feature1', 'Feature2', 'block_id'], as_index=False).agg(
    Start=('Start', 'min'),
    End=('End', agg_end)
)[['Id', 'Start', 'End', 'Feature1', 'Feature2']]

print(result)

运行后输出结果和预期完全匹配:

Id      Start        End  Feature1  Feature2
0  A 2020-01-01 2020-01-30         1         1
1  A 2020-01-31 2020-02-15         0         1
2  A 2020-07-01 2020-07-15         0         1
3  B 2020-01-31        NaT         0         0

关键说明

  • 排序是必要前提,必须保证同组内日期按升序排列,否则连续判断会出错
  • 如果业务场景的连续间隔不是1天,只需修改pd.Timedelta(days=1)的参数即可适配
  • End列的聚合逻辑已经做了NaT兼容,只要同一个连续块里存在NaT,合并后的End就返回NaT

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 14:45:04