如何按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
相关产品推荐
相关产品推荐

