python 中的双边移动平均线

Two-sided moving average in python

您好,我有一些数据,我想计算中心移动平均线或两侧移动平均线。

我知道使用 numpy.convolve 函数可以很容易地做到这一点,我想知道是否有一种简单或类似的方法可以做到这一点,但是当平均值需要是两个时-支持。

如果区间包含三个条目,则单边移动平均线通常按以下方式工作,N = 3:

import numpy
list = [3, 4, 7, 8, 9, 10]
N = 3
window = numpy.repeat(1., N)/N
moving_avg = numpy.convolve(list, window, 'valid')
moving_avg = array([ 4.66666667,  6.33333333,  8.        ,  9.        ])

现在我的目标是获得居中的平均值,因此如果 N = 3,则取平均值的区间为:[[3, 4, 7], [4, 7, 8]、[7、8、9]、[8、9、10]]。如果 N 是偶数,这也很棘手。有没有工具可以计算这个?我更愿意通过编写函数或使用 numpy 来实现。

和评论者一样,我也很困惑你想要完成的事情与你展示的方式不同。

无论如何,我确实想提供一个解决方案,让您可以使用 Numba's @stencil decorator:

编写自己的卷积运算
from numba import stencil

@stencil
def ma(a):
    return (a[-1] + a[0] + a[1]) / 3

data = np.array([3, 4, 7, 8, 9, 10])
print(ma(data))
[0.         4.66666667 6.33333333 8.         9.         0.        ]

不确定这是否正是您要找的,但是模板操作员很棒。您传递给它的变量代表一个给定的元素,您使用的任何索引都是相对于该元素的。如您所见,制作 3 元素 window 来计算移动平均值非常容易。

希望这能满足您的需求。

使用大社区

你可以给模版添加一个参数,它是包容性的。让我们以 9 为邻域:

@stencil(neighborhood = ((-4, 4),))
def ma(a):
    cumul = 0
    for i in range(-4, 5):
        cumul += a[i]
    return cumul / 9

您可以使用 (-8, 0) 或 (0, 8) 向前或向后移动范围并更改范围。

设置 N 邻居

不确定这是否是最好的方法,但我用包装器完成了它:

def wrapper(data, N):
    @nb.stencil(neighborhood = ((int(-(N-1)/2), int((N-1)/2)),))
    def ma(a):
        cumul = 0
        for i in np.arange(int(-(N-1)/2), int((N-1)/2)+1):
            cumul += a[i]
        return cumul / N
    return ma(data)

同样,索引很奇怪,因此您必须尝试使用​​它才能获得所需的效果。