在 Python 中计算移动平均值

2025年3月17日 | 阅读13分钟

在本教程中,我们将学习如何在Python中计算时间序列数据的移动平均线。移动平均线是一种统计度量,指的是从固定长度的数据列表中获得的一组平均值。这些数据值是时间序列数据中总观测值的子集。

假设我们有一个长度为n的时间序列数据值集合,并且在任何时间t我们必须考虑的窗口长度为k。然后,我们通过取前k个数据值的平均值、接下来的k个数据值等来计算移动平均值。窗口在整个数组中保持相同的长度。当窗口的高端与数组的末尾重合时,我们停止该过程。

示例

让我们以时间序列 ts = [1, 2, 3, 6, 7],窗口长度 k = 3 为例。我们将首先计算前三个项的平均值,并将该值存储在移动平均线列表中。这个平均值对应于数组 ts 的哪个数据值是另一个话题。现在,我们将窗口移动一个索引,使窗口从数组的第二个元素开始,到第四个元素结束。我们将计算平均值并将其添加到列表中。重复此步骤后,窗口的高端加一将与数组的末尾重合。因此,该过程完成。

我们将看到如何在Python中实现这个算法

代码

输出

Window 1: [1, 2, 3] has an average of: 2.0
Window 2: [2, 3, 6] has an average of: 3.67
Window 3: [3, 6, 8] has an average of: 5.67
The moving averages are: [2.0, 3.67, 5.67]

简单移动平均线

SMA是最基本的移动平均线类型。它包括给定k个周期的值的平均值,其中这些值具有等于1的权重。分析师使用SMA来分析或衡量当前或未来的趋势。它假设过去和当前或最近的观测值在预测未来趋势中具有相同的贡献。我们还将看到一些移动平均线的类型,它们可以反驳这一假设。

计算SMA的公式

Calculate Moving Averages in Python

其中,

SMAi 是第i个窗口的简单移动平均线

k 是任何时间 t 的窗口大小

yi + j 是来自具有j滞后性的观测值集合的第i个值。

方法 1

我们将使用Python的Numpy模块。Numpy模块简化了数组的求和与求平均。我们将使用sum()函数来查找数组元素的总和。

代码

输出

The moving averages are: [2.0, 3.67, 5.67]

方法 2

在此方法中,我们将使用Python的Pandas库。该库提供了一种更简单的方法来计算给定时间序列观测数据的简单移动平均线。Pandas有一个内置方法,可以提供任何指定大小的滚动窗口。因此,我们必须使用此函数来获取不同窗口的值。然后,我们将计算每个窗口值的平均值。我们将对窗口-序列对象应用另一个Pandas函数来计算平均值。我们不能在Numpy数组或Python数据结构上应用滚动函数。因此,我们必须将数组转换为Pandas序列对象才能应用此函数。

代码

输出

Raw list:  [nan, nan, 2.0, 3.6666666666666665, 5.666666666666667]
The final list of Simple Moving Averages:  [2.0, 3.6666666666666665, 5.666666666666667]

累积移动平均线

另一种移动平均线是累积移动平均线。要计算CMA,我们首先计算时间序列观测值的累积和。然后我们取累积平均值。这个平均值用于时间序列数据的分析。

公式

Calculate Moving Averages in Python

其中

CMAt 是任何时间 t 的累积移动平均线

Kt 是到特定时间 t 的观测总数

yi 是时间序列数据数组的第i个元素

方法 1

我们将首先使用Numpy来解决这个问题。Numpy提供了一种查找累积和数组的简单方法。我们将首先创建一个样本数据的Numpy数组,并通过内置的Numpy函数cum_sum()创建累积和数组。当我们遍历每个值时,计算平均值并将其存储在移动平均线列表中。

代码

输出

The cumulative sum of observations:  [ 1 
3  6 12 20]
The Cumulative Moving Average is:  [1.0, 1.5, 2.0, 3.0, 4.0]

方法 2

这次我们将使用Pandas库。Pandas库也提供了一个内置函数来计算观测数组的累积和。其函数Series.expanding()跨越所有观测值,窗口大小为[1, 数组长度]。虽然它不提供总和,但它只会返回范围[1, n]中的n个窗口,其中n = 数组长度。我们将使用Series.mean()函数来查找每个窗口观测值的平均值。

代码

输出

The Cumulative Moving Average is:  [1.0, 1.5, 2.0, 3.0, 4.0]

指数移动平均线

另一种移动平均线是指数移动平均线。我们通过取时间序列数据的加权平均值来计算EMA。EMA和WMA的区别在于EMA中的权重随着时间的推移呈指数下降。因此,它被称为指数移动平均线。这种类型的移动平均线在捕捉趋势方面速度非常快。它之所以快,是因为它对我们正在研究的时期内的观测值的波动或变化稍微更敏感。这一特性使得EMA对于时间序列数据的短期分析非常有效。

公式

Calculate Moving Averages in Python

EMAt 是时间 t 的观测值的指数移动平均线

Kt 是第t个观测值的指数平滑常数

Ct 是时间 t 的观测值

Pt - 1 是时间周期 t - 1 的EMA

方法 1

我们将通过编写自己的算法来解决这个问题,以找到给定时间序列的EMA。

代码

输出

The EMA values are: 
 [1, 1.28, 1.76, 2.95, 4.36]

方法 2

我们将在本例中使用Pandas库来计算EMA。Pandas库提供了一个内置方法Series.ewm(com)。此方法旨在从给定的数据序列中找到指数加权窗口的Pandas序列。我们需要给函数一个com值。根据上面的公式,K = 1 / (1 + com)。这样,权重将由函数计算,并乘以我们附加了该函数的时间序列数据。K的值始终在0到1之间。

代码

输出

The list of Exponential Moving Averages: [1.0, 1.5833333333333333, 2.220183486238532, 3.6801801801801797, 5.196316328022218]

加权移动平均线(WMA)

一些分析师认为,最近的值在通过时间序列测量趋势时比旧数据更重要。因此,他们创建了加权移动平均线。WMA的计算几乎与SMA相同。主要区别在于数据将在此处乘以预定义的权重。

权重应遵循某些条件

  • 权重之和应始终为1
  • 权重应根据时间序列递增。也就是说,最近的数据比之前的数据具有更高的权重。

计算WMA的公式

Calculate Moving Averages in Python

其中,

WMAi 是第i个窗口的加权移动平均线

k 是任何时间 t 的窗口大小

yi + j 是来自具有j滞后性的观测值集合的第i个值。

wj 是窗口的第j个观测值的权重

方法 1

我们将首先使用Python的Numpy模块。我们将使用与计算SMA相同的逻辑。区别在于我们将同时遍历权重数组,并利用Numpy数组的逐元素乘法,将数据乘以权重。然后,我们将找到乘积序列的总和以及当前窗口权重的总和。将这两个数相除,我们将得到当前窗口的加权平均值。

代码

输出

The weighted moving averages: [2.33, 4.11, 6.08]

方法 2

在此方法中,我们将使用Python的Pandas库。该库提供了一种更简单的方法来计算给定时间序列观测数据的简单移动平均线。Pandas有一个内置方法,可以提供任何指定大小的滚动窗口。因此,我们必须使用此函数来获取不同窗口的值。然后,我们将计算每个窗口值的平均值。我们将对窗口-序列对象应用另一个Pandas函数来计算平均值。我们不能在Numpy数组或Python数据结构上应用滚动函数。因此,我们需要将数组转换为Pandas序列对象才能应用此函数。

代码

输出

Raw list:  [nan, nan, 2.0, 3.6666666666666665, 5.666666666666667]
The final list of Simple Moving Averages:  [2.0, 3.6666666666666665, 5.666666666666667]

应用

时间序列分析:它平滑短期波动,并突出长期观测值,如趋势和周期。

财务分析:它用于股票市场的金融分析,例如计算股票价格和回报以及分析市场趋势。

环境工程:它用于分析环境条件,同时考虑各种因素,如污染物浓度等。

计算机性能分析:它用于通过计算平均CPU利用率、进程队列长度等指标来分析计算机性能。