在数据处理时,我们为了平滑数据,有时会用到滑动平均算法。算法很简单,但是我不想自己写,于是上网搜现成的轮子,但是发现很多轮子是错误的,如文章:https://blog.csdn.net/weixin_42232219/article/details/90328880,https://www.yzlfxy.com/jiaocheng/python/338117.html
他们混淆了滑动平均与均值滤波的区别,用卷积的方式实现滑动平均。如:
import numpy as np
def np_move_avg(a,n,mode="same"):
return(np.convolve(a, np.ones((n,))/n, mode=mode))
然而,滑动平均与均值滤波是两种不同的算法。
滑动平均中有一个动量的概念,是用动量参与加权和的计算。
而均值滤波中没有动量的概念,是使用原始数据进行均值/加权和计算。
具体差异就是:与当前元素计算加权和的元素的来源不同。均值滤波是利用平滑前的数据;滑动平均是利用平滑后的数据。
具体差异见以下代码(在差异的代码后面有注释):
def moving_average(scalars,weight=0.85):
"""
滑动平均算法
:param scalars: 单层列表
:param weight: 滑动平均权重(last的权重)
:return:
"""
last = scalars[0]
smoothed = [scalars[0]]
for point in scalars:
smoothed_value = last * weight + (1 - weight) * point
smoothed.append(smoothed_value)
last = smoothed_value # 用smoothed[-1]参与下一步的加权和计算
return smoothed
def mean_smooth(scalars,weight=0.85):
"""
均值滤波
:param scalars: 单层列表
:param weight: 加权和权重
:return:
"""
last = scalars[0]
smoothed = [scalars[0]]
for index,point in enumerate(1,scalars):
smoothed_value = last * weight + (1 - weight) * point
smoothed.append(smoothed_value)
last = point #用scalars的元素参与下一个环节的加权和计算
return smoothed