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

如何按pid分组,生成记录obs_occurred==1时最近date的新列?

解决方案

核心思路是先标记出obs_occurred==1对应的有效日期,再在每个pid分组内向前填充这些有效日期,就能得到每行对应的最近上一个有效日期。

步骤1:生成仅包含有效日期的临时列

先创建临时列,只保留obs_occurred == 1时的date值,其余位置设为NaN:

df['temp_date'] = df['date'].where(df['obs_occurred'] == 1)

步骤2:分组后向前填充有效日期

对每个pid分组,用ffill()(向前填充)填充临时列的NaN值,这样每行就能获取到最近的上一个有效日期(第一行若obs_occurred为1,会保留自身日期):

df['shift'] = df.groupby('pid')['temp_date'].ffill()

步骤3:清理临时列(可选)

不需要临时列的话可以直接删除:

df.drop('temp_date', axis=1, inplace=True)

完整示例代码

import pandas as pd

# 构造示例数据
data = {
    'obs_occurred': [1.0, 1.0, 0.0, 1.0, 1.0],
    'pid': [10000001]*5,
    'date': pd.to_datetime(['2016-01-06', '2016-01-07', '2016-01-08', '2016-01-09', '2016-01-10'])
}
df = pd.DataFrame(data)

# 生成目标列
df['temp_date'] = df['date'].where(df['obs_occurred'] == 1)
df['shift'] = df.groupby('pid')['temp_date'].ffill()
df.drop('temp_date', axis=1, inplace=True)

print(df)

运行后输出与示例一致:

obs_occurred       pid       date      shift
0           1.0  10000001 2016-01-06 2016-01-06
1           1.0  10000001 2016-01-07 2016-01-06
2           0.0  10000001 2016-01-08 2016-01-07
3           1.0  10000001 2016-01-09 2016-01-07
4           1.0  10000001 2016-01-10 2016-01-09

补充说明

  • where()方法会保留满足条件的值,不满足的替换为NaN,精准筛选出所有有效日期
  • ffill()(向前填充)会沿分组内的行方向,用最近的非NaN值填充当前NaN,完美匹配“最近上一个有效日期”的需求
  • 若某个pid的前几行obs_occurred都是0,ffill会保留NaN,可根据需求用fillna()补充默认值

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 11:27:06