如何用Python的hpfilter从时间序列提取trend component和cyclical component?
HP滤波提取时间序列趋势与周期成分技术指导
1. 原始时间序列数据
你提供的时间序列数据如下:
Year Z-value 0 1976-01-01 9.170293 1 1977-01-01 9.130933 2 1978-01-01 9.092142 3 1979-01-01 9.179282 4 1980-01-01 9.031123 5 1981-01-01 8.899608 6 1982-01-01 8.533545 7 1983-01-01 8.648138 8 1984-01-01 8.895921 9 1985-01-01 9.035276 10 1986-01-01 8.898070 11 1987-01-01 9.096961 12 1988-01-01 9.267598 13 1989-01-01 9.270736 14 1990-01-01 9.051413 15 1991-01-01 8.798996 16 1992-01-01 8.821594 17 1993-01-01 8.959126 18 1994-01-01 9.226342 19 1995-01-01 9.453473 20 1996-01-01 9.608805 21 1997-01-01 9.939561 22 1998-01-01 10.030579 23 1999-01-01 10.481201 24 2000-01-01 11.027884 25 2001-01-01 11.023259 26 2002-01-01 11.031710 27 2003-01-01 11.101627 28 2004-01-01 11.321485 29 2005-01-01 11.548922 30 2006-01-01 11.394613 31 2007-01-01 11.238485 32 2008-01-01 11.094884 33 2009-01-01 10.289895 34 2010-01-01 10.493154 35 2011-01-01 10.618517 36 2012-01-01 10.455861 37 2013-01-01 10.617282 38 2014-01-01 10.600950 39 2015-01-01 10.194091 40 2016-01-01 10.212243 41 2017-01-01 10.662858 42 2018-01-01 10.750010
2. 修正后可运行的完整代码
你原代码中存在z变量未定义的问题,以下是包含数据加载、滤波计算和可视化的完整代码:
import pandas as pd import numpy as np import matplotlib.pyplot as plt import statsmodels.api as sm import seaborn as sns sns.set() # 加载数据并转为时间序列格式 data = pd.DataFrame({ 'Year': pd.date_range(start='1976-01-01', periods=43, freq='Y'), 'Z-value': [9.170293,9.130933,9.092142,9.179282,9.031123,8.899608,8.533545,8.648138,8.895921,9.035276,8.898070,9.096961,9.267598,9.270736,9.051413,8.798996,8.821594,8.959126,9.226342,9.453473,9.608805,9.939561,10.030579,10.481201,11.027884,11.023259,11.031710,11.101627,11.321485,11.548922,11.394613,11.238485,11.094884,10.289895,10.493154,10.618517,10.455861,10.617282,10.600950,10.194091,10.212243,10.662858,10.750010] }) data.set_index('Year', inplace=True) # 提取Z-value列作为滤波输入 z = data['Z-value'] # 执行HP滤波,lambda参数设为43 cycle, trend = sm.tsa.filters.hpfilter(z, lamb=43) # 可视化原始序列与趋势成分 plt.figure(figsize=(12,6)) plt.plot(z, label='原始Z值', color='gray', alpha=0.5) plt.plot(trend, label='趋势成分', color='blue') plt.title('原始Z值与HP滤波趋势对比') plt.xlabel('年份') plt.ylabel('数值') plt.legend() plt.show() # 可视化周期成分 plt.figure(figsize=(12,6)) plt.plot(cycle, label='周期成分', color='red') plt.title('HP滤波周期成分') plt.xlabel('年份') plt.ylabel('周期波动值') plt.legend() plt.show()
3. 核心操作说明
- 数据预处理:将年份设为索引并转为时间序列格式,确保statsmodels能正确识别序列的时间结构。
- HP滤波调用:
sm.tsa.filters.hpfilter()返回顺序为周期(cycle)在前,趋势(trend)在后,注意变量接收顺序;参数lamb是平滑系数,年度数据常用值为100,你设置的43会让趋势更贴近原始数据,数值越大趋势曲线越平滑。 - 成分提取:
trend:原始序列的长期趋势部分,反映Z值的整体走向cycle:原始序列减去趋势后的波动部分,代表短期偏离趋势的周期变化
4. 结果解读
- 趋势成分:能清晰看到1990年后Z值整体上升,2008年出现回落,之后又逐步回升的长期规律。
- 周期成分:数值为正表示当期Z值高于长期趋势,为负则低于趋势,比如2009年周期值为负,说明当年Z值显著低于长期趋势水平。
内容的提问来源于stack exchange,提问作者businesstoe
相关产品推荐
相关产品推荐

