You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 07:55:19