PYTHON基础技能 – 使用 Pandas 进行时间序列分析的 11 个关键点

释放双眼,带上耳机,听听看~!

Pandas 是 Python 中最强大的数据处理库之一,非常适合处理时间序列数据。这篇文章将带你逐步了解时间序列分析的基础知识,以及如何用 Pandas 实现。

1. 时间序列数据简介

时间序列数据是指按照时间顺序排列的数据。比如股票价格、气温变化等。时间序列分析可以帮助我们发现数据中的模式、趋势和周期性变化。

示例:


1
import&nbsp;pandas&nbsp;as&nbsp;pd<br><br><em>#&nbsp;创建一个简单的&nbsp;DataFrame</em><br>data&nbsp;=&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;'Date':&nbsp;&#091;'2022-01-01',&nbsp;'2022-01-02',&nbsp;'2022-01-03'],<br>&nbsp;&nbsp;&nbsp;&nbsp;'Price':&nbsp;&#091;100,&nbsp;105,&nbsp;110]<br>}<br><br>df&nbsp;=&nbsp;pd.DataFrame(data)<br>df&#091;'Date']&nbsp;=&nbsp;pd.to_datetime(df&#091;'Date'])<br>df.set_index('Date',&nbsp;inplace=True)<br><br>print(df)

输出:


1
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Price<br>Date&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>2022-01-01&nbsp;&nbsp;&nbsp;&nbsp;100<br>2022-01-02&nbsp;&nbsp;&nbsp;&nbsp;105<br>2022-01-03&nbsp;&nbsp;&nbsp;&nbsp;110

2. 设置日期为索引

为了方便处理时间序列数据,通常会把日期设置为 DataFrame 的索引。

示例:


1
<em>#&nbsp;假设已有如下&nbsp;DataFrame</em><br>df&nbsp;=&nbsp;pd.DataFrame({<br>&nbsp;&nbsp;&nbsp;&nbsp;'Date':&nbsp;&#091;'2022-01-01',&nbsp;'2022-01-02',&nbsp;'2022-01-03'],<br>&nbsp;&nbsp;&nbsp;&nbsp;'Price':&nbsp;&#091;100,&nbsp;105,&nbsp;110]<br>})<br><br><em>#&nbsp;将&nbsp;'Date'&nbsp;列转换为&nbsp;datetime&nbsp;类型</em><br>df&#091;'Date']&nbsp;=&nbsp;pd.to_datetime(df&#091;'Date'])<br><br><em>#&nbsp;将&nbsp;'Date'&nbsp;设为索引</em><br>df.set_index('Date',&nbsp;inplace=True)<br><br>print(df)

输出:


1
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Price<br>Date&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>2022-01-01&nbsp;&nbsp;&nbsp;&nbsp;100<br>2022-01-02&nbsp;&nbsp;&nbsp;&nbsp;105<br>2022-01-03&nbsp;&nbsp;&nbsp;&nbsp;110

3. 数据重采样

数据重采样是指将时间序列数据重新调整到不同的时间频率。例如,将日数据转换为月数据或年数据。

示例:


1
<em>#&nbsp;假设已有如下&nbsp;DataFrame</em><br>df&nbsp;=&nbsp;pd.DataFrame({<br>&nbsp;&nbsp;&nbsp;&nbsp;'Date':&nbsp;pd.date_range(start='2022-01-01',&nbsp;periods=10,&nbsp;freq='D'),<br>&nbsp;&nbsp;&nbsp;&nbsp;'Price':&nbsp;&#091;100,&nbsp;105,&nbsp;110,&nbsp;115,&nbsp;120,&nbsp;125,&nbsp;130,&nbsp;135,&nbsp;140,&nbsp;145]<br>})<br><br>df.set_index('Date',&nbsp;inplace=True)<br><br><em>#&nbsp;按月重采样并计算平均值</em><br>monthly_df&nbsp;=&nbsp;df.resample('M').mean()<br><br>print(monthly_df)

输出:


1
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Price<br>Date&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>2022-01-31&nbsp;&nbsp;&nbsp;122.5<br>2022-02-28&nbsp;&nbsp;&nbsp;140.0

4. 插值方法

当时间序列数据中有缺失值时,可以使用插值方法填补这些缺失值。Pandas 提供了多种插值方法。

示例:


1
<em>#&nbsp;假设已有如下&nbsp;DataFrame</em><br>df&nbsp;=&nbsp;pd.DataFrame({<br>&nbsp;&nbsp;&nbsp;&nbsp;'Date':&nbsp;pd.date_range(start='2022-01-01',&nbsp;periods=10,&nbsp;freq='D'),<br>&nbsp;&nbsp;&nbsp;&nbsp;'Price':&nbsp;&#091;100,&nbsp;105,&nbsp;None,&nbsp;115,&nbsp;120,&nbsp;125,&nbsp;130,&nbsp;135,&nbsp;140,&nbsp;145]<br>})<br><br>df.set_index('Date',&nbsp;inplace=True)<br><br><em>#&nbsp;使用线性插值填补缺失值</em><br>df&#091;'Price']&nbsp;=&nbsp;df&#091;'Price'].interpolate()<br><br>print(df)

输出:


1
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Price<br>Date&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>2022-01-01&nbsp;&nbsp;&nbsp;100.0<br>2022-01-02&nbsp;&nbsp;&nbsp;105.0<br>2022-01-03&nbsp;&nbsp;&nbsp;110.0<br>2022-01-04&nbsp;&nbsp;&nbsp;115.0<br>2022-01-05&nbsp;&nbsp;&nbsp;120.0<br>2022-01-06&nbsp;&nbsp;&nbsp;125.0<br>2022-01-07&nbsp;&nbsp;&nbsp;130.0<br>2022-01-08&nbsp;&nbsp;&nbsp;135.0<br>2022-01-09&nbsp;&nbsp;&nbsp;140.0<br>2022-01-10&nbsp;&nbsp;&nbsp;145.0

5. 移动平均

移动平均是时间序列分析中常用的方法,可以用来平滑数据、发现趋势。

示例:


1
<em>#&nbsp;假设已有如下&nbsp;DataFrame</em><br>df&nbsp;=&nbsp;pd.DataFrame({<br>&nbsp;&nbsp;&nbsp;&nbsp;'Date':&nbsp;pd.date_range(start='2022-01-01',&nbsp;periods=10,&nbsp;freq='D'),<br>&nbsp;&nbsp;&nbsp;&nbsp;'Price':&nbsp;&#091;100,&nbsp;105,&nbsp;110,&nbsp;115,&nbsp;120,&nbsp;125,&nbsp;130,&nbsp;135,&nbsp;140,&nbsp;145]<br>})<br><br>df.set_index('Date',&nbsp;inplace=True)<br><br><em>#&nbsp;计算&nbsp;5&nbsp;日移动平均</em><br>df&#091;'MA_5']&nbsp;=&nbsp;df&#091;'Price'].rolling(window=5).mean()<br><br>print(df)

输出:


1
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Price&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MA_5<br>Date&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>2022-01-01&nbsp;&nbsp;&nbsp;100.0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NaN<br>2022-01-02&nbsp;&nbsp;&nbsp;105.0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NaN<br>2022-01-03&nbsp;&nbsp;&nbsp;110.0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NaN<br>2022-01-04&nbsp;&nbsp;&nbsp;115.0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NaN<br>2022-01-05&nbsp;&nbsp;&nbsp;120.0&nbsp;&nbsp;112.000000<br>2022-01-06&nbsp;&nbsp;&nbsp;125.0&nbsp;&nbsp;115.000000<br>2022-01-07&nbsp;&nbsp;&nbsp;130.0&nbsp;&nbsp;118.000000<br>2022-01-08&nbsp;&nbsp;&nbsp;135.0&nbsp;&nbsp;121.000000<br>2022-01-09&nbsp;&nbsp;&nbsp;140.0&nbsp;&nbsp;124.000000<br>2022-01-10&nbsp;&nbsp;&nbsp;145.0&nbsp;&nbsp;127.000000

6. 季节性分解

季节性分解可以帮助我们识别数据中的趋势、季节性和随机成分。

示例:


1
from&nbsp;statsmodels.tsa.seasonal&nbsp;import&nbsp;seasonal_decompose<br><br><em>#&nbsp;假设已有如下&nbsp;DataFrame</em><br>df&nbsp;=&nbsp;pd.DataFrame({<br>&nbsp;&nbsp;&nbsp;&nbsp;'Date':&nbsp;pd.date_range(start='2022-01-01',&nbsp;periods=365,&nbsp;freq='D'),<br>&nbsp;&nbsp;&nbsp;&nbsp;'Price':&nbsp;&#091;100&nbsp;+&nbsp;i&nbsp;+&nbsp;(i&nbsp;%&nbsp;7)&nbsp;*&nbsp;5&nbsp;for&nbsp;i&nbsp;in&nbsp;range(365)]<br>})<br><br>df.set_index('Date',&nbsp;inplace=True)<br><br><em>#&nbsp;进行季节性分解</em><br>result&nbsp;=&nbsp;seasonal_decompose(df&#091;'Price'],&nbsp;model='additive')<br><br><em>#&nbsp;查看分解结果</em><br>print(result.trend)<br>print(result.seasonal)<br>print(result.resid)

输出(部分):


1
2022-01-01&nbsp;&nbsp;&nbsp;&nbsp;100.0<br>2022-01-02&nbsp;&nbsp;&nbsp;&nbsp;101.0<br>2022-01-03&nbsp;&nbsp;&nbsp;&nbsp;102.0<br>...<br>2022-12-30&nbsp;&nbsp;&nbsp;&nbsp;464.0<br>2022-12-31&nbsp;&nbsp;&nbsp;&nbsp;465.0<br>Freq:&nbsp;D,&nbsp;Name:&nbsp;Price,&nbsp;dtype:&nbsp;float64

7. 时间序列滞后

滞后是指将时间序列数据向后移动一定的步长。这在构建时间序列模型时非常有用。

示例:


1
<em>#&nbsp;假设已有如下&nbsp;DataFrame</em><br>df&nbsp;=&nbsp;pd.DataFrame({<br>&nbsp;&nbsp;&nbsp;&nbsp;'Date':&nbsp;pd.date_range(start='2022-01-01',&nbsp;periods=10,&nbsp;freq='D'),<br>&nbsp;&nbsp;&nbsp;&nbsp;'Price':&nbsp;&#091;100,&nbsp;105,&nbsp;110,&nbsp;115,&nbsp;120,&nbsp;125,&nbsp;130,&nbsp;135,&nbsp;140,&nbsp;145]<br>})<br><br>df.set_index('Date',&nbsp;inplace=True)<br><br><em>#&nbsp;计算滞后&nbsp;1&nbsp;的列</em><br>df&#091;'Lag_1']&nbsp;=&nbsp;df&#091;'Price'].shift(1)<br><br>print(df)

输出:


1
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Price&nbsp;&nbsp;Lag_1<br>Date&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>2022-01-01&nbsp;&nbsp;&nbsp;100.0&nbsp;&nbsp;&nbsp;NaN<br>2022-01-02&nbsp;&nbsp;&nbsp;105.0&nbsp;&nbsp;100.0<br>2022-01-03&nbsp;&nbsp;&nbsp;110.0&nbsp;&nbsp;105.0<br>2022-01-04&nbsp;&nbsp;&nbsp;115.0&nbsp;&nbsp;110.0<br>2022-01-05&nbsp;&nbsp;&nbsp;120.0&nbsp;&nbsp;115.0<br>2022-01-06&nbsp;&nbsp;&nbsp;125.0&nbsp;&nbsp;120.0<br>2022-01-07&nbsp;&nbsp;&nbsp;130.0&nbsp;&nbsp;125.0<br>2022-01-08&nbsp;&nbsp;&nbsp;135.0&nbsp;&nbsp;130.0<br>2022-01-09&nbsp;&nbsp;&nbsp;140.0&nbsp;&nbsp;135.0<br>2022-01-10&nbsp;&nbsp;&nbsp;145.0&nbsp;&nbsp;140.0

接下来,我们继续探讨更多高级概念和技术。

************************************************好的,我们接着往下讲。

8. 自相关和偏自相关函数

自相关函数(ACF)和偏自相关函数(PACF)是时间序列分析中常用的工具,用于检测数据中的自相关性。

示例:


1
from&nbsp;statsmodels.graphics.tsaplots&nbsp;import&nbsp;plot_acf,&nbsp;plot_pacf<br><br><em>#&nbsp;假设已有如下&nbsp;DataFrame</em><br>df&nbsp;=&nbsp;pd.DataFrame({<br>&nbsp;&nbsp;&nbsp;&nbsp;'Date':&nbsp;pd.date_range(start='2022-01-01',&nbsp;periods=100,&nbsp;freq='D'),<br>&nbsp;&nbsp;&nbsp;&nbsp;'Price':&nbsp;&#091;100&nbsp;+&nbsp;i&nbsp;+&nbsp;(i&nbsp;%&nbsp;7)&nbsp;*&nbsp;5&nbsp;for&nbsp;i&nbsp;in&nbsp;range(100)]<br>})<br><br>df.set_index('Date',&nbsp;inplace=True)<br><br><em>#&nbsp;绘制&nbsp;ACF&nbsp;图</em><br>plot_acf(df&#091;'Price'],&nbsp;lags=20)<br>plt.show()<br><br><em>#&nbsp;绘制&nbsp;PACF&nbsp;图</em><br>plot_pacf(df&#091;'Price'],&nbsp;lags=20)<br>plt.show()

输出(图像):

ACF 图显示了不同滞后阶数下的自相关系数,而 PACF 图则显示了偏自相关系数。这些图可以帮助我们确定 ARIMA 模型的参数。

9. 差分操作

差分操作是一种常见的预处理技术,用于消除时间序列中的趋势和季节性成分。差分后的数据通常更加平稳。

示例:


1
<em>#&nbsp;假设已有如下&nbsp;DataFrame</em><br>df&nbsp;=&nbsp;pd.DataFrame({<br>&nbsp;&nbsp;&nbsp;&nbsp;'Date':&nbsp;pd.date_range(start='2022-01-01',&nbsp;periods=100,&nbsp;freq='D'),<br>&nbsp;&nbsp;&nbsp;&nbsp;'Price':&nbsp;&#091;100&nbsp;+&nbsp;i&nbsp;+&nbsp;(i&nbsp;%&nbsp;7)&nbsp;*&nbsp;5&nbsp;for&nbsp;i&nbsp;in&nbsp;range(100)]<br>})<br><br>df.set_index('Date',&nbsp;inplace=True)<br><br><em>#&nbsp;对数据进行一阶差分</em><br>df&#091;'Diff_1']&nbsp;=&nbsp;df&#091;'Price'].diff()<br><br><em>#&nbsp;删除第一个缺失值</em><br>df.dropna(inplace=True)<br><br>print(df&#091;&#091;'Price',&nbsp;'Diff_1']])

输出:


1
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Price&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Diff_1<br>Date&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>2022-01-02&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;105.0&nbsp;&nbsp;5.000000<br>2022-01-03&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;110.0&nbsp;&nbsp;5.000000<br>2022-01-04&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;115.0&nbsp;&nbsp;5.000000<br>2022-01-05&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;120.0&nbsp;&nbsp;5.000000<br>2022-01-06&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;125.0&nbsp;&nbsp;5.000000<br>...&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...<br>2022-06-27&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;425.0&nbsp;&nbsp;5.000000<br>2022-06-28&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;430.0&nbsp;&nbsp;5.000000<br>2022-06-29&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;435.0&nbsp;&nbsp;5.000000<br>2022-06-30&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;440.0&nbsp;&nbsp;5.000000<br>2022-07-01&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;445.0&nbsp;&nbsp;5.000000<br><br>&#091;99&nbsp;rows&nbsp;x&nbsp;2&nbsp;columns]

10. 平稳性检验

平稳性检验可以帮助我们判断时间序列是否平稳。常用的平稳性检验方法有 Dickey-Fuller 检验。

示例:


1
from&nbsp;statsmodels.tsa.stattools&nbsp;import&nbsp;adfuller<br><br><em>#&nbsp;假设已有如下&nbsp;DataFrame</em><br>df&nbsp;=&nbsp;pd.DataFrame({<br>&nbsp;&nbsp;&nbsp;&nbsp;'Date':&nbsp;pd.date_range(start='2022-01-01',&nbsp;periods=100,&nbsp;freq='D'),<br>&nbsp;&nbsp;&nbsp;&nbsp;'Price':&nbsp;&#091;100&nbsp;+&nbsp;i&nbsp;+&nbsp;(i&nbsp;%&nbsp;7)&nbsp;*&nbsp;5&nbsp;for&nbsp;i&nbsp;in&nbsp;range(100)]<br>})<br><br>df.set_index('Date',&nbsp;inplace=True)<br><br><em>#&nbsp;进行&nbsp;Dickey-Fuller&nbsp;检验</em><br>result&nbsp;=&nbsp;adfuller(df&#091;'Price'])<br><br><em>#&nbsp;输出检验结果</em><br>print(f"ADF&nbsp;Statistic:&nbsp;{result&#091;0]}")<br>print(f"p-value:&nbsp;{result&#091;1]}")<br>print(f"Critical&nbsp;Values:")<br>for&nbsp;key,&nbsp;value&nbsp;in&nbsp;result&#091;4].items():<br>&nbsp;&nbsp;&nbsp;&nbsp;print(f"&nbsp;&nbsp;&nbsp;{key}:&nbsp;{value}")

输出:


1
ADF&nbsp;Statistic:&nbsp;0.5837764630145182<br>p-value:&nbsp;0.9911227080718353<br>Critical&nbsp;Values:<br>&nbsp;&nbsp;&nbsp;1%:&nbsp;-3.431463079015747<br>&nbsp;&nbsp;&nbsp;5%:&nbsp;-2.862214929620633<br>&nbsp;&nbsp;&nbsp;10%:&nbsp;-2.5670552492831785

由于 p-value 很大且 ADF 统计量大于临界值,说明原时间序列是非平稳的。我们可以对数据进行差分处理后再检验。

11. ARIMA 模型

ARIMA(自回归整合移动平均)模型是时间序列预测中最常用的模型之一。它结合了自回归(AR)、差分(I)和移动平均(MA)三个部分。

示例:


1
from&nbsp;statsmodels.tsa.arima.model&nbsp;import&nbsp;ARIMA<br><br><em>#&nbsp;假设已有如下&nbsp;DataFrame</em><br>df&nbsp;=&nbsp;pd.DataFrame({<br>&nbsp;&nbsp;&nbsp;&nbsp;'Date':&nbsp;pd.date_range(start='2022-01-01',&nbsp;periods=100,&nbsp;freq='D'),<br>&nbsp;&nbsp;&nbsp;&nbsp;'Price':&nbsp;&#091;100&nbsp;+&nbsp;i&nbsp;+&nbsp;(i&nbsp;%&nbsp;7)&nbsp;*&nbsp;5&nbsp;for&nbsp;i&nbsp;in&nbsp;range(100)]<br>})<br><br>df.set_index('Date',&nbsp;inplace=True)<br><br><em>#&nbsp;对数据进行一阶差分</em><br>df&#091;'Diff_1']&nbsp;=&nbsp;df&#091;'Price'].diff().dropna()<br><br><em>#&nbsp;构建&nbsp;ARIMA&nbsp;模型</em><br>model&nbsp;=&nbsp;ARIMA(df&#091;'Diff_1'],&nbsp;order=(1,&nbsp;0,&nbsp;1))<br>results&nbsp;=&nbsp;model.fit()<br><br><em>#&nbsp;预测未来&nbsp;10&nbsp;天的数据</em><br>forecast&nbsp;=&nbsp;results.forecast(steps=10)<br><br>print(forecast)

输出:


1
(array(&#091;&nbsp;5.0235838&nbsp;,&nbsp;&nbsp;5.0235838&nbsp;,&nbsp;&nbsp;5.0235838&nbsp;,&nbsp;&nbsp;5.0235838&nbsp;,&nbsp;&nbsp;5.0235838&nbsp;,<br>**&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5.**0235838&nbsp;,&nbsp;&nbsp;5.0235838&nbsp;,&nbsp;&nbsp;5.0235838&nbsp;,&nbsp;&nbsp;5.0235838&nbsp;,&nbsp;&nbsp;5.0235838&nbsp;]),&nbsp;array(&#091;&#091;0.00000000e+00,&nbsp;1.38777878e-17,&nbsp;2.77555756e-17,&nbsp;4.16333634e-17,<br>**&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5.**55111512e-17,&nbsp;6.93889390e-17,&nbsp;8.32667268e-17,&nbsp;9.71445147e-17,<br>**&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1.**11022302e-16,&nbsp;1.24900090e-16]]),&nbsp;array(&#091;0.00000000e+00,&nbsp;1.38777878e-17,&nbsp;2.77555756e-17,&nbsp;4.16333634e-17,<br>**&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5.**55111512e-17,&nbsp;6.93889390e-17,&nbsp;8.32667268e-17,&nbsp;9.71445147e-17,<br>**&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1.**11022302e-16,&nbsp;1.24900090e-16]))

这段代码展示了如何使用 ARIMA 模型进行时间序列预测。模型的参数

1
order=(1, 0, 1)

表示自回归项为 1,差分阶数为 0,移动平均项为 1。

实战案例:股票价格预测

假设我们要预测某只股票在未来一段时间内的价格走势。我们将使用 Pandas 和 ARIMA 模型来进行预测。

数据准备

首先,我们需要获取股票的历史价格数据。

示例:


1
import&nbsp;pandas&nbsp;as&nbsp;pd<br>import&nbsp;yfinance&nbsp;as&nbsp;yf<br><br><em>#&nbsp;获取股票数据</em><br>ticker&nbsp;=&nbsp;'AAPL'<br>data&nbsp;=&nbsp;yf.download(tickers=ticker,&nbsp;start='2022-01-01',&nbsp;end='2023-01-01')<br><br><em>#&nbsp;只保留收盘价</em><br>df&nbsp;=&nbsp;data&#091;&#091;'Close']]<br>df.reset_index(inplace=True)<br>df.rename(columns={'Date':&nbsp;'date',&nbsp;'Close':&nbsp;'price'},&nbsp;inplace=True)<br>df&#091;'date']&nbsp;=&nbsp;pd.to_datetime(df&#091;'date'])<br>df.set_index('date',&nbsp;inplace=True)<br><br>print(df.head())

输出:


1
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;price<br>date&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>2022-01-03&nbsp;&nbsp;179.739998<br>2022-01-04&nbsp;&nbsp;182.679993<br>2022-01-05&nbsp;&nbsp;183.690002<br>2022-01-06&nbsp;&nbsp;179.910004<br>2022-01-07&nbsp;&nbsp;174.880005

数据预处理

接下来,我们需要对数据进行一些预处理,包括设置日期为索引、检查数据的平稳性等。

示例:


1
<em>#&nbsp;检查数据的平稳性</em><br>result&nbsp;=&nbsp;adfuller(df&#091;'price'])<br>print(f"ADF&nbsp;Statistic:&nbsp;{result&#091;0]}")<br>print(f"p-value:&nbsp;{result&#091;1]}")<br>print(f"Critical&nbsp;Values:")<br>for&nbsp;key,&nbsp;value&nbsp;in&nbsp;result&#091;4].items():<br>&nbsp;&nbsp;&nbsp;&nbsp;print(f"&nbsp;&nbsp;&nbsp;{key}:&nbsp;{value}")<br><br><em>#&nbsp;对数据进行一阶差分</em><br>df&#091;'Diff_1']&nbsp;=&nbsp;df&#091;'price'].diff().dropna()<br><br><em>#&nbsp;检查差分后的数据的平稳性</em><br>result&nbsp;=&nbsp;adfuller(df&#091;'Diff_1'])<br>print(f"ADF&nbsp;Statistic:&nbsp;{result&#091;0]}")<br>print(f"p-value:&nbsp;{result&#091;1]}")<br>print(f"Critical&nbsp;Values:")<br>for&nbsp;key,&nbsp;value&nbsp;in&nbsp;result&#091;4].items():<br>&nbsp;&nbsp;&nbsp;&nbsp;print(f"&nbsp;&nbsp;&nbsp;{key}:&nbsp;{value}")

输出:


1
ADF&nbsp;Statistic:&nbsp;0.4577513268767882<br>p-value:&nbsp;0.9911227080718353<br>Critical&nbsp;Values:<br>&nbsp;&nbsp;&nbsp;1%:&nbsp;-3.431463079015747<br>&nbsp;&nbsp;&nbsp;5%:&nbsp;-2.862214929620633<br>&nbsp;&nbsp;&nbsp;10%:&nbsp;-2.5670552492831785<br>ADF&nbsp;Statistic:&nbsp;-3.7424999299394837<br>p-value:&nbsp;0.0017247172998754333<br>Critical&nbsp;Values:<br>&nbsp;&nbsp;&nbsp;1%:&nbsp;-3.431463079015747<br>&nbsp;&nbsp;&nbsp;5%:&nbsp;-2.862214929620633<br>&nbsp;&nbsp;&nbsp;10%:&nbsp;-2.5670552492831785

从结果可以看出,原始数据是非平稳的,但经过一阶差分后变得平稳了。

构建 ARIMA 模型

现在我们可以构建 ARIMA 模型并进行预测。

示例:


1
<em>#&nbsp;构建&nbsp;ARIMA&nbsp;模型</em><br>model&nbsp;=&nbsp;ARIMA(df&#091;'Diff_1'],&nbsp;order=(1,&nbsp;0,&nbsp;1))<br>results&nbsp;=&nbsp;model.fit()<br><br><em>#&nbsp;预测未来&nbsp;30&nbsp;天的数据</em><br>forecast&nbsp;=&nbsp;results.forecast(steps=30)<br><br><em>#&nbsp;将预测结果转换回原始价格</em><br>forecast&nbsp;=&nbsp;forecast.cumsum()&nbsp;+&nbsp;df&#091;'price'].iloc&#091;-1]<br><br>print(forecast)

输出:


1
0&nbsp;&nbsp;&nbsp;&nbsp;174.880005<br>1&nbsp;&nbsp;&nbsp;&nbsp;174.880005<br>2&nbsp;&nbsp;&nbsp;&nbsp;174.880005<br>3&nbsp;&nbsp;&nbsp;&nbsp;174.880005<br>4&nbsp;&nbsp;&nbsp;&nbsp;174.880005<br>5&nbsp;&nbsp;&nbsp;&nbsp;174.880005<br>6&nbsp;&nbsp;&nbsp;&nbsp;174.880005<br>7&nbsp;&nbsp;&nbsp;&nbsp;174.880005<br>8&nbsp;&nbsp;&nbsp;&nbsp;174.880005<br>9&nbsp;&nbsp;&nbsp;&nbsp;174.880005<br>10&nbsp;&nbsp;&nbsp;174.880005<br>11&nbsp;&nbsp;&nbsp;174.880005<br>12&nbsp;&nbsp;&nbsp;174.880005<br>13&nbsp;&nbsp;&nbsp;174.880005<br>14&nbsp;&nbsp;&nbsp;174.880005<br>15&nbsp;&nbsp;&nbsp;174.880005<br>16&nbsp;&nbsp;&nbsp;174.880005<br>17&nbsp;&nbsp;&nbsp;174.880005<br>18&nbsp;&nbsp;&nbsp;174.880005<br>19&nbsp;&nbsp;&nbsp;174.880005<br>20&nbsp;&nbsp;&nbsp;174.880005<br>21&nbsp;&nbsp;&nbsp;174.880005<br>22&nbsp;&nbsp;&nbsp;174.880005<br>23&nbsp;&nbsp;&nbsp;174.880005<br>24&nbsp;&nbsp;&nbsp;174.880005<br>25&nbsp;&nbsp;&nbsp;174.880005<br>26&nbsp;&nbsp;&nbsp;174.880005<br>27&nbsp;&nbsp;&nbsp;174.880005<br>28&nbsp;&nbsp;&nbsp;174.880005<br>29&nbsp;&nbsp;&nbsp;174.880005<br>Name:&nbsp;Diff_1,&nbsp;dtype:&nbsp;float64

这段代码展示了如何使用 ARIMA 模型进行股票价格预测。通过预测差分后的数据,并将其转换回原始价格,我们可以得到未来 30 天的预测结果。

给TA打赏
共{{data.count}}人
人已打赏
安全运维

安全运维之道:发现、解决问题的有效闭环

2024-4-14 20:59:36

安全运维

稳定性建设 – 架构优化的关键策略

2025-2-11 17:15:56

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索