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

如何在Pandas的groupby.shift中处理闰年问题

解决方法:用日期匹配替代行偏移

你想用groupby.shift的思路有个核心问题:它依赖连续无缺失的日度数据,而且没法自动处理闰年的日期调整。更靠谱的做法是先算出每个日期对应的「去年同期日期」,再通过关联匹配拿到对应金额。

步骤1:计算去年对应日期

针对闰年2月29日的特殊情况,我们可以写个简单的日期转换逻辑:

  • 普通日期直接减1年
  • 如果原日期是2月29日,且减1年后变成2月28日(说明前一年是平年,没有2月29),就自动调整为3月1日

代码实现:

import pandas as pd

def get_last_year_date(current_date):
    last_year_date = current_date - pd.DateOffset(years=1)
    # 处理闰年2月29日的特殊情况
    if current_date.month == 2 and current_date.day == 29:
        if last_year_date.month == 2 and last_year_date.day == 28:
            last_year_date += pd.DateOffset(days=1)
    return last_year_date

# 给原数据添加去年日期列
data['last_year_date'] = data['date'].apply(get_last_year_date)

步骤2:关联匹配去年金额

把原数据复制一份,重命名日期和金额列,然后通过location和last_year_date做左连接,就能匹配到对应去年的金额:

# 复制原数据,用于匹配去年金额
last_year_data = data[['location', 'date', 'amount']].rename(
    columns={'date': 'last_year_date', 'amount': '1_year_ago_amnt'}
)

# 左连接,确保每个原数据行都能拿到对应的去年金额(没有则为NaN)
data = pd.merge(
    data,
    last_year_data,
    on=['location', 'last_year_date'],
    how='left'
)

完整示例

假设你的数据结构如下(date必须是datetime类型):

# 测试数据
data = pd.DataFrame({
    'location': ['A', 'A', 'A', 'B', 'B'],
    'date': pd.to_datetime(['2020-02-28', '2020-02-29', '2021-03-01', '2020-02-29', '2021-03-01']),
    'amount': [100, 200, 150, 300, 250]
})

运行上面的代码后,你会看到:

  • 2020-02-29的last_year_date是2019-03-01
  • 若需要2021-03-01匹配2020-02-29的金额,可以调整函数逻辑(比如检查当前日期是3月1日且前一年是闰年时,替换为前一年的2月29),现有逻辑已覆盖你描述的闰年核心问题。

为什么不推荐用shift?

  1. 依赖连续数据:如果某个location某天没有数据,shift会偏移错误的行,导致金额对应错误。
  2. 闰年处理不了:2020年有366天,2021年有365天,固定shift(365)或shift(366)都会导致日期错位。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 13:08:12