如何用Python通过ACF自动提取时间序列的峰峰周期值
Python从ACF结果自动识别时间序列周期实现方案
核心逻辑是定位ACF曲线上排除lag=0初始峰值后的连续显著局部极大值,相邻峰值的滞后步长差即为序列周期。
实现步骤
- 计算序列ACF值,设置的最大滞后步长需至少覆盖2倍预估周期长度,保证能捕获至少两个连续周期峰值
- 过滤lag=0位置的恒值峰值(该位置ACF值恒为1,不属于周期相关的有效峰值)
- 用峰值检测算法识别满足高度阈值、最小间距要求的局部极大值,过滤噪声导致的微小假峰
- 取前两个有效峰值对应的滞后步长做差,得到整数周期值
可直接运行的代码实现
依赖库:numpy、statsmodels、scipy,可通过pip直接安装。
import numpy as np from statsmodels.tsa.stattools import acf from scipy.signal import find_peaks def get_acf_period(ts, max_lag=300, peak_height_thresh=0.2, min_peak_gap=10): """ 从ACF计算结果自动提取峰峰周期 :param ts: 1维numpy数组格式的输入时间序列 :param max_lag: ACF计算的最大滞后步长,需大于2倍预估周期 :param peak_height_thresh: ACF峰值最小高度阈值,用于过滤噪声假峰 :param min_peak_gap: 两个峰值之间的最小间隔,避免把主峰旁的小波动误判为独立峰值 :return: 整数周期值、ACF数组、有效峰值对应的lag列表 """ # 计算ACF值 acf_arr = acf(ts, nlags=max_lag, adjusted=False) # 跳过lag=0的位置,从lag=1开始检测峰值 search_range = acf_arr[1:] # 检测满足条件的局部峰值 peaks, _ = find_peaks(search_range, height=peak_height_thresh, distance=min_peak_gap) # 还原峰值对应的实际lag值(补回跳过的lag=0偏移) valid_peak_lags = peaks + 1 if len(valid_peak_lags) < 2: raise RuntimeError("有效峰值数量不足,请调大max_lag参数、降低peak_height_thresh阈值后重试") # 相邻峰值间隔即为周期 period = valid_peak_lags[1] - valid_peak_lags[0] return int(period), acf_arr, valid_peak_lags
参数调整说明
- 若检测不到足够峰值:适当调大
max_lag保证覆盖至少2个周期,或降低peak_height_thresh阈值适配低自相关性的序列 - 若识别出的周期偏小(误把小波动当峰值):适当调高
peak_height_thresh、增大min_peak_gap参数,过滤噪声干扰 - 针对示例中96步周期的场景,设置
max_lag=200、peak_height_thresh=0.2即可稳定识别出正确周期值
内容的提问来源于stack exchange,提问作者Pradya Panyainkaew
相关产品推荐
相关产品推荐

