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

Python Pandas中按组用下一行start_dt填充end_dt列的优化方案

更简洁的缓慢变化维度(SCD)日期填充方案

嘿,你的这个需求用Pandas的shift()方法就能完美解决,比你当前的合并方案简洁高效得多!咱们一步步来实现:

核心思路

我们需要先按Key分组,组内按start_dt排序保证顺序正确,然后直接用shift(-1)获取每组内下一行的start_dt,赋值给当前行的end_dt即可,最后一行自然会保留NA,完全符合你的期望。

完整实现代码

import pandas as pd

# 假设你的原始DataFrame是这样的
df = pd.DataFrame({
    'Key': [1, 1, 1, 2, 2],
    'start_dt': ['25-05-2019', '30-06-2019', '15-07-2019', '17-07-2019', '15-07-2019'],
    'end_dt': [pd.NA, pd.NA, pd.NA, pd.NA, pd.NA]
})

# 第一步:把start_dt转为datetime类型,确保排序逻辑正确
df['start_dt'] = pd.to_datetime(df['start_dt'], format='%d-%m-%Y')

# 第二步:按Key分组,组内按start_dt升序排序
df = df.sort_values(['Key', 'start_dt']).reset_index(drop=True)

# 第三步:用shift(-1)获取每组下一行的start_dt,赋值给end_dt
df['end_dt'] = df.groupby('Key')['start_dt'].shift(-1)

# 可选:把日期转回原字符串格式(如果需要的话)
df['start_dt'] = df['start_dt'].dt.strftime('%d-%m-%Y')
df['end_dt'] = df['end_dt'].dt.strftime('%d-%m-%Y').where(df['end_dt'].notna(), pd.NA)

print(df)

输出结果

Key   start_dt     end_dt
0    1  25-05-2019  30-06-2019
1    1  30-06-2019  15-07-2019
2    1  15-07-2019       <NA>
3    2  15-07-2019  17-07-2019
4    2  17-07-2019       <NA>

为什么这个方案更优?

  • 代码简洁:不需要生成额外的seq列,也不需要拆分、重命名、合并DataFrame,几行代码就能完成。
  • 性能更好:避免了合并操作的开销,尤其是当你的数据量很大时,groupby+shift的组合比合并两个DataFrame高效得多。
  • 逻辑清晰:直接对应你的需求——“每组内下一行的start_dt作为当前行的end_dt”,代码语义明确,可读性强。

关键方法解释

  • pd.to_datetime(..., format='%d-%m-%Y'):确保日期字符串被正确解析为datetime类型,避免字符串排序时出现的逻辑错误(比如跨月日期的字符串排序可能不符合时间顺序)。
  • groupby('Key')['start_dt'].shift(-1):在每个Key分组内,将start_dt列向上偏移一位(即取当前行的下一行值),分组的最后一行没有下一行,所以会返回NA,正好符合你的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:28:08