用adfuller做ADF检验需先观察序列趋势并正确设定regression参数,对异方差序列应先变换(如取对数),使用autolag="AIC"自动选滞后阶数,仅关注pvalue与icbest,注意test_statistic须比临界值更负才拒绝原假设,输入必须为1D numpy数组且无缺失值。

怎么用 adfuller 做 ADF 检验?别直接扔原始序列
ADF 检验不是“调个函数就完事”的黑盒,adfuller 对输入序列很敏感。原始时间序列常含趋势或截距,直接喂给 adfuller 很可能得出“非平稳”的误判——其实只是模型设定没对上。
实操建议:
- 先画图看趋势:
plt.plot(series),有明显上扬/下降线?大概率得选regression="ct"(带常数+时间趋势) - 若序列均值稳定但方差炸了(比如波动越来越大),ADF 本身不处理异方差,得先做变换(如取对数、
np.log1p)再检验 -
adfuller默认用regression="c"(只带常数项),对带线性趋势的序列容易漏检单位根,这时候 p 值偏大,误以为平稳 - 滞后阶数
maxlag别硬写数字,让函数自动选:adfuller(x, autolag="AIC"),否则阶数太小会残留自相关,太大又损失自由度
adfuller 返回的五个值里,只看 pvalue 和 icbest 就够了
返回元组是 (test_statistic, pvalue, usedlag, nobs, critical_values, icbest),但日常判断只盯两个数:p 值是否小于 0.05,以及 icbest(AIC/BIC 选的最优滞后阶数)是否合理。其他字段基本不用查。
常见错误现象:
立即学习“Python免费学习笔记(深入)”;
- p 值 = 0.12,但
icbest= 1,而你数据有 500 个点——说明滞后阶数严重不足,自相关没剔干净,得手动加大maxlag再试 -
critical_values是字典,含"1%"、"5%"、"10%"三档临界值,但比这个更关键的是:你的test_statistic必须比对应显著性水平的临界值更负才算拒绝原假设。比如test_statistic = -2.8,而"5%"临界值是-2.86,那就不算通过 - 别把
nobs当样本量——它等于原始长度减去滞后阶数,所以短序列 + 高滞后 = 有效观测极少,结果不可靠
差分后还非平稳?别急着三阶差分,先检查季节性或结构突变
一阶差分后 pvalue > 0.05 很常见,但这不意味着必须二阶差分。过度差分会引入虚假随机性,反而破坏可预测性。
使用场景和排查点:
- 月度销售数据在差分后仍不平稳?大概率是季节性没处理,先用
seasonal_decompose或detrend+period=12剥离季节项,再对残差做 ADF - 序列在某年份突然跳变(比如政策调整)?ADF 假设结构稳定,这种断点会让检验失效。得先用
changepoint库检测突变点,分段检验 - 金融收益率序列常“看起来平稳”,但 ADF 却卡在 p=0.07 —— 这时候别硬差分,考虑用 PP 检验(
kpss或phillips_perron)交叉验证,它对异方差更鲁棒
为什么 adfuller 在 pandas DataFrame 上直接报错 ValueError: array must be 1-dimensional?
因为 adfuller 只吃 1D 数组,而 df["col"] 返回的是 pd.Series,看着像一维,但内部 dtype 或索引可能触发隐式转换失败;df[["col"]] 更惨,返回的是二维 DataFrame。
安全写法就一条:
- 永远用
adfuller(df["col"].dropna().values)——.values强制转成numpy.ndarray,dropna()防空值干扰 - 别信
df["col"].to_numpy(),某些版本 pandas 会保留 NaN,导致adfuller报错 - 如果序列含
datetime索引,不影响检验,但别把它当数据传进去;adfuller不读索引,只看数值
最易被忽略的一点:ADF 检验本身不关心时间间隔是否等距,但它假设观测独立同分布(除自相关外)。如果你的采样严重不均匀(比如日频数据里缺了三个月),检验结果会失真——这时候得先插值或重采样,再跑 adfuller。









