Pandas获取去年年初至今日期并与今年同期数据对比报错解决方案
问题排查
- 核心逻辑错误:你当前用
dt.day(月内第几天)筛选日期的逻辑完全不符合YTD同期对比需求。比如当前日期为11月29日,仅判断日小于29的话,去年1月30日会被误过滤,去年12月1日会被误保留,完全偏离需求。 - 代码笔误:今年YTD筛选的代码行中,你误用
sales_data_this_year的布尔条件过滤sales_data_last_year,两个DataFrame索引、行数不匹配会触发pandas自动对齐逻辑,产生缺失值,这是你触发类型报错的直接原因。 - 冗余操作:重复调用
pd.to_datetime转换同一列日期,属于无效代码。
修复方案
直接对比日期的「月+日」部分即可精准筛选同期YTD数据,无需拆分判断年月日,也能兼容闰年特殊情况:
import datetime import pandas as pd # 仅需执行一次日期格式转换 sales_data_df['Date'] = pd.to_datetime(sales_data_df['Date']) # 取当前年份、去年年份、当前月日标识(格式为MMDD,如11月29日为1129) current_year = datetime.datetime.now().year last_year = current_year - 1 current_md = datetime.datetime.now().strftime("%m%d") # 筛选去年同期YTD数据 sales_data_last_ytd = sales_data_df[ (sales_data_df['Date'].dt.year == last_year) & (sales_data_df['Date'].dt.strftime("%m%d") <= current_md) ] # 去年数据聚合计算 last_ytd_agg = sales_data_last_ytd.groupby('Id').agg( Quantity=('Quantity', 'sum'), NetAmount=('NetAmount', 'sum') ).reset_index() last_ytd_agg['COGS_last_YTD'] = last_ytd_agg['Quantity'] * last_ytd_agg['NetAmount'] # 筛选今年YTD数据 sales_data_this_ytd = sales_data_df[ (sales_data_df['Date'].dt.year == current_year) & (sales_data_df['Date'].dt.strftime("%m%d") <= current_md) ] # 今年数据聚合计算 this_ytd_agg = sales_data_this_ytd.groupby('Id').agg( Quantity=('Quantity', 'sum'), NetAmount=('NetAmount', 'sum') ).reset_index() this_ytd_agg['COGS_YTD'] = this_ytd_agg['Quantity'] * this_ytd_agg['NetAmount'] # 按需合并两年数据方便对比 final_compare_df = pd.merge( last_ytd_agg, this_ytd_agg, on='Id', how='outer', suffixes=('_last_year', '_current_year') )
方案优势
- 用月日字符串对比的逻辑天然适配闰年场景:如果当前不是闰年的2月29日,会自动忽略去年闰年的2月29日数据,符合同期对比的通用规则。
- 所有筛选操作都基于原DataFrame执行,不存在多表索引对齐的问题,从根源上避免类型不匹配报错。
- 代码逻辑清晰易维护,后续如果需要调整对比规则,只需修改
current_md的生成规则即可。
内容的提问来源于stack exchange,提问作者Murcielago
相关产品推荐
相关产品推荐

