一维数组的加权平滑 - Python

Weighted smoothing of a 1D array - Python

我是 Python 的新手,我有一些参数检测数组,其中一些值检测不正确(例如 4555555):

array = [1, 20, 55, 33, 4555555, 1]

而且我想以某种方式平滑它。现在我用加权平均值来做:

def smoothify(array):
    for i in range(1, len(array) - 2):
        array[i] = 0.7 * array[i] + 0.15 * (array[i - 1] + array[i + 1])
    return array

但它的效果很差,当然,我们可以对 3 个以上的元素取加权平均值,但它会导致复制粘贴...我试图为此找到一些本机函数,但我失败了。

你能帮我一下吗?

P.S。对不起,如果这是一个菜鸟问题:(

感谢您的宝贵时间, 最好的问候,安娜

也许您想看看 numpy,尤其是 numpy.average。 还有,你看到这个问题了吗Weighted moving average in python?也可能有帮助。

因为你用 numpy 标记了这个,我写了我将如何用 numpy 做这个:

import numpy as np

def smoothify(thisarray):
    """
    returns moving average of input using:
    out(n) = .7*in(n) + 0.15*( in(n-1) + in(n+1) )
    """

    # make sure we got a numpy array, else make it one
    if type(thisarray) == type([]): thisarray = np.array(thisarray)

    # do the moving average by adding three slices of the original array
    # returns a numpy array,
    # could be modified to return whatever type we put in...
    return 0.7 * thisarray[1:-1] + 0.15 * ( thisarray[2:] + thisarray[:-2] )

myarray = [1, 20, 55, 33, 4555555, 1]
smootharray = smoothify(myarray)

不是循环遍历原始数组,使用 numpy 你可以通过索引得到 "slices"。输出数组将比输入数组短两项。中心点 (n) 是这个数组[1:-1] : "From item index 1 until the last item (not inclusive)"。其他切片是 "From index 2 until the end" 和 "Everything except the last two"

会建议 numpy.average 来帮助您。诀窍是计算权重 - 下面我压缩了三个列表 - 一个与原始数组相同,前一步,后一步。一旦我们有了权重,我们就将它们输入 np.average 函数

import numpy as np
array = [1, 20, 55, 33, 4555555, 1]
arrayCompare = zip(array, array[1:] + [0], [0] + array)

weights = [.7 * x + .15 * (y + z) for x, y, z in arrayCompare]

avg = np.average(array, weights=weights)

出于加权平滑的目的,您基本上希望对矢量化解决方案执行 convolution. For our case, since we are dealing with 1D arrays, we can simply use NumPy's 1D convolution function : np.convolve。这里唯一要记住的重要事情是,考虑到卷积的性质,使用在主输入数组上滑动的内核的反转版本,权重将被反转。因此,解决方案是 -

weights = [0.7,0.15,0.15]
out = np.convolve(array,np.array(weights)[::-1],'same')

如果您想要获得加权平均值,您可以使用 out/sum(weights) 获得那些。在我们的例子中,由于给定权重的总和已经是 1,因此输出将保持与 out.

相同

让我们绘制输出和输入以进行图形调试 -

# Input array and weights
array = [1, 20, 55, 33, 455, 200, 100, 20 ]
weights = [0.7,0.15,0.15]

out = np.convolve(array,np.array(weights)[::-1],'same')

x = np.arange(len(array))
f, axarr = plt.subplots(2, sharex=True, sharey=True)
axarr[0].plot(x,array)
axarr[0].set_title('Original and smoothened arrays')
axarr[1].plot(x,out)

输出-