如何用Pandas基于特定值偏移生成最近GP就诊日期列?
问题描述
原始DataFrame如下:
| Type | Scheduled |
|---|---|
| GP | 08/09/2019 |
| Blood | 09/09/2019 |
| Urine | 10/09/2019 |
| GP | 11/09/2019 |
| GP | 20/09/2019 |
| Physio | 20/09/2019 |
需要新增一列Last GP,记录每行对应的最近一次GP就诊日期,最终效果如下:
| Type | Scheduled | Last GP |
|---|---|---|
| GP | 08/09/2019 | nan |
| Blood | 09/09/2019 | 08/09/2019 |
| Urine | 10/09/2019 | 08/09/2019 |
| GP | 11/09/2019 | 08/09/2019 |
| GP | 20/09/2019 | 11/09/2019 |
| Physio | 20/09/2019 | 20/09/2019 |
尝试过基于条件的shift操作但无法实现,考虑过逐行分析或拆分DataFrame查找,但希望找到更简便的方案。
解决方案
可以通过Pandas的where、ffill和shift组合实现,无需逐行遍历,步骤如下:
import pandas as pd # 构造原始数据 data = { 'Type': ['GP', 'Blood', 'Urine', 'GP', 'GP', 'Physio'], 'Scheduled': ['08/09/2019', '09/09/2019', '10/09/2019', '11/09/2019', '20/09/2019', '20/09/2019'] } df = pd.DataFrame(data) # 1. 将日期列转换为datetime类型,确保日期逻辑正确 df['Scheduled'] = pd.to_datetime(df['Scheduled'], format='%d/%m/%Y') # 2. 提取Type为GP的日期,其他行填充NaN df['gp_dates'] = df['Scheduled'].where(df['Type'] == 'GP') # 3. 向前填充(ffill),得到每行当前及之前最近的GP日期 df['gp_ffill'] = df['gp_dates'].ffill() # 4. 生成Last GP列:GP行取上一次的GP日期(shift后的ffill值),非GP行直接用最近的GP日期 df['Last GP'] = df['gp_ffill'].shift(1).where(df['Type'] == 'GP', df['gp_ffill']) # 5. 转换回原日期字符串格式,清理临时列 df['Last GP'] = df['Last GP'].dt.strftime('%d/%m/%Y').replace('NaT', 'nan') df['Scheduled'] = df['Scheduled'].dt.strftime('%d/%m/%Y') df = df.drop(['gp_dates', 'gp_ffill'], axis=1) # 输出结果 print(df)
逻辑说明:
where:筛选出所有GP类型的就诊日期,其他行留空;ffill:向前填充空值,让每一行都能获取到截至当前行最近的GP日期(包括当天的);shift(1):对GP行,需要的是上一次的GP日期,因此将填充后的日期向下偏移一行,第一行GP会得到NaN,符合需求;- 最后转换回原日期格式并清理临时列,得到目标结果。
内容的提问来源于stack exchange,提问作者Paul O
相关产品推荐
相关产品推荐

