用shift()计算环比/同比增幅需先按时间升序排序并重置索引,环比用shift(1),同比依周期选shift(12)等;须转datetime索引以保障时间语义,配合div()或np.where处理nan和除零,避免链式赋值警告。

用 shift() 计算环比增幅:注意时间顺序和缺失值
环比增幅 = (本期值 − 上期值) / 上期值,核心是把上期数据“错位”拉下来对齐。必须确保数据已按时间升序排列,否则 shift(1) 拉的不是上一期。shift() 默认向下移动(即当前行对应上一行),所以排序错误会导致结果完全颠倒。
常见错误现象:shift(1) 后第一行变成 NaN,直接参与除法会得 NaN;若原始数据有重复日期或未排序,同比/环比值会错配。
- 先执行
df.sort_values('date', inplace=True),再重置索引(df.reset_index(drop=True, inplace=True))避免索引干扰 - 计算时用
df['value'].shift(1)获取上期值,不要用df['value'].shift(-1)(那是下期) - 用
df['value'].pct_change()可一步替代手动计算,但底层仍是shift()+ 除法,且同样受排序影响
用 shift() 计算同比增幅:关键在周期参数和频率对齐
同比需要拉前一年同期数据,不是简单 shift(1)。具体数值取决于时间粒度:月度数据通常用 shift(12),季度用 shift(4),周度用 shift(52)。但前提是数据是规则采样、无缺失——如果某个月缺数,shift(12) 会跨到错误月份。
使用场景:财报月报、销售日报等固定周期数据。若原始 date 是字符串,必须先转为 datetime 并设为索引,否则 shift() 只按行数移,不感知时间语义。
快速生成专业的 Python 脚本和应用代码。一键创建完整项目结构,支持CLI、API、爬虫、Bot、Django等多种项目类型,包含完整的项目结构、配置文件、依赖管理、测试、README和文档。
- 正确做法:
df['date'] = pd.to_datetime(df['date'])→df = df.set_index('date').sort_index()→ 再用shift(12) - 若存在不规则间隔(如节假日跳空),优先考虑
resample('M').sum().pct_change(12)或asfreq('M')插值对齐 -
shift(12)对日频数据无效——它只数行,不识别“去年今天”,此时应改用df.shift(freq='12M')(需索引为 DatetimeIndex)
处理 NaN 和除零:别让空值污染整列结果
shift() 必然在开头产生 NaN,而原始数据中可能有零值(如销售额为 0),直接做除法会触发 ZeroDivisionError 或产出 inf。Pandas 默认容忍 0 / 0 → NaN、1 / 0 → inf,但这在业务报表中不可接受。
- 安全计算环比:
df['mom_growth'] = df['value'].div(df['value'].shift(1)).sub(1)该写法中div()遇NaN或0自动返回NaN,比/运算符更鲁棒 - 显式过滤零分母:
prev = df['value'].shift(1); df['yoy_growth'] = np.where(prev != 0, (df['value'] - prev) / prev, np.nan) - 业务上常要求“同比为 0 的月份,增幅显示为空”,此时直接保留
NaN即可,后续用.fillna('—')格式化输出
性能与链式赋值警告:避免 SettingWithCopyWarning
直接写 df['growth'] = ... 在某些视图(view)场景下会触发警告,尤其当 df 来自 df.loc[...] 切片时。shift() 本身不改变原数据,但赋值操作可能意外写入副本。
- 始终用
df = df.copy()显式复制后再计算,或确认df._is_copy is None - 避免链式写法:
df.loc[:, 'growth'] = ...比df['growth'] = ...更明确作用域 - 百万行以上数据慎用
pct_change(periods=12)—— 它内部也是shift(),但封装层略慢于裸shift()+ 手动运算
实际中最容易被忽略的是时间索引的完整性:即使你写了 shift(12),只要原始数据里 2023 年 2 月缺值,2024 年 2 月的同比就会拿 2023 年 1 月的数据来算。验证方法很简单——打印 df.index.freq,如果不是 'M' 或 'D' 等明确频率,就别信 shift(n) 的业务含义。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










