Python DataFrame中如何根据另一列日期填充对应结束日期?
高效填充对应Start行的End值需求
原始数据:
| Date | Start | End |
|---|---|---|
| 01/02/2023 22:00 | 01/02/2023 05:00 | |
| 01/02/2023 23:00 | ||
| 02/02/2023 00:00 | 02/02/2023 00:00 | |
| 02/02/2023 01:00 | 02/02/2023 01:00 | |
| 02/02/2023 02:00 | ||
| 02/02/2023 03:00 | 02/02/2023 03:00 |
期望结果:
| Date | Start | End |
|---|---|---|
| 01/02/2023 22:00 | 01/02/2023 05:00 | 02/02/2023 00:00 |
| 01/02/2023 23:00 | ||
| 02/02/2023 00:00 | 02/02/2023 00:00 | |
| 02/02/2023 01:00 | 02/02/2023 01:00 | 02/02/2023 03:00 |
| 02/02/2023 02:00 | ||
| 02/02/2023 03:00 | 02/02/2023 03:00 |
高效实现方法
可以通过标记Start分组 + 定向填充End值的方式一次性完成,避免先bfill()再清理的冗余操作:
代码实现(Pandas)
import pandas as pd # 构造原始数据 data = { 'Date': ['01/02/2023 22:00', '01/02/2023 23:00', '02/02/2023 00:00', '02/02/2023 01:00', '02/02/2023 02:00', '02/02/2023 03:00'], 'Start': ['01/02/2023 05:00', '', '', '02/02/2023 01:00', '', ''], 'End': ['', '', '02/02/2023 00:00', '', '', '02/02/2023 03:00'] } df = pd.DataFrame(data) # 空字符串转NaN,方便后续处理 df[['Start', 'End']] = df[['Start', 'End']].replace('', pd.NA) # 生成分组ID:每个非空Start行触发分组ID递增 df['group_id'] = df['Start'].notna().cumsum() # 分组内向前填充End值,仅赋值给有Start值的行 df.loc[df['Start'].notna(), 'End'] = df.groupby('group_id')['End'].ffill() # 移除临时分组列 df = df.drop('group_id', axis=1) # 可选:将NaN转回空字符串 df = df.fillna('') print(df)
原理说明
- 分组标记:
df['Start'].notna().cumsum()会为每一行生成分组ID,每遇到一个非空的Start行,分组ID就递增,这样每个Start行到下一个Start行之间的所有行属于同一组; - 定向填充:分组内对End列向前填充(
ffill()),让每个分组的Start行自动获取到该组内最后一个有效的End值; - 精准赋值:通过
loc只修改有Start值的行的End字段,其他行保持原状态,无需后续清理操作。
这种方法直接定位目标行完成填充,避免了全表填充后再过滤的无效操作,效率更高且逻辑清晰。
内容的提问来源于stack exchange,提问作者Nazmi Husaini
相关产品推荐
相关产品推荐

