2.12 真实数据的噪声平滑处理

2.12 真实数据的噪声平滑处理

前言:来自各种真实世界传感器的数据通常是不平滑和不干净的,也包含了一些我们不想在显示在图表或者图形的噪声。

1、操作步骤

(1)基础算法是基于滚动窗口模式(rolling window)
(2)窗口滚动过数据,然后计算出窗口内数据的平均值
(3)对于离散数据,我们使用Numpy的convolve方法;它返回两个一维序列的离散纤细卷积。

2、工作原理

平滑数据噪声的一个简单朴素的方法就是:对窗口(样本)求平均值;然后绘制出给定窗口的平均值,而不是所有数据点。

代码实现:

"""
真实数据噪声平滑处理
"""
from pylab import *
from numpy import *

def moving_average(interval,window_size):
    '''
    计算给定大小的卷积窗口
    :param interval:
    :param window_size:
    :return:
    '''
    #方法ones定义了一个所有元素值为1的序列或者矩阵(例如多维数组)。
    # 我们用它来生成用于求平均值的窗口。
    window=ones(int(window_size))/float(window_size)
    return convolve(interval,window,'same')

#在指定的时间间隔内得到一些均匀间隔的数字。
t=linspace(-4,4,100)
y=sin(t)+randn(len(t))*0.1

plot(t,y,"k.")
#计算移动平均数
y_av=moving_average(y,10)
plot(t,y_av,"r")
xlabel("Time")
ylabel("value")
grid(True)
show()

运行测试:

2.12 真实数据的噪声平滑处理_第1张图片
从图上我们可以看出平滑数据处理后的曲线和原始数据之间的对比情况。

3、沿着上面的思路,我们可以开始一个更高级的例子
(1)基于信号窗口的卷积

代码实现:

"""
使用现有的SciPy库来让窗口平滑处理达到更好的效果
"""
import numpy
from numpy import *
from pylab import *
#可能的窗口类型
WINDOWS=['flat','hanning','hamming','bartlett','blackman']
def smooth(x,window_len=11,window='hanning'):
    """
    使用要求大小的窗口平滑数据。返回平滑信号。
    :param x:输入信号
    :param window_len:平滑窗长
    :param window:窗口类型
    :return:
    """
    if x.ndim!=1:
        raise(ValueError,"smooth只接受一维数组")
    if x.size<window_len:
        raise(ValueError,"输入向量需要大于窗口大小")
    if window_len<3:
        return x
    if not window in WINDOWS:
        raise (ValueError,"Window is one of 'flat', 'hanning', 'hamming', "
                          "'bartlett', 'blackman'")
    #在前面和后面添加反射窗口,减小了数据的边界效应
    s=numpy.r_[x[window_len-1:0:-1],x,x[-1:-window_len:-1]]
    #选择窗口类型并做平均
    if window=='flat':
        w=numpy.ones(window_len,'d')
    else:
        #在numpy中调用适当的函数(call appropriate function in numpy)
        w=eval('numpy.'+window+'(window_len)')
    #注:长度(输出)=长度(输入),要更正:
    #返回y[(window_len/2-1):-(window_len/2)]而不仅仅是y
    y=numpy.convolve(w/w.sum(),s,mode='valid')
    return y
#在指定的时间间隔内得到一些均匀间隔的数字。
t=linspace(-4,4,100)
#制造一些嘈杂的正弦
x=sin(t)
xn=x+randn(len(t))*0.1
#把它磨平
y=smooth(x)
ws=31
subplot(211)
plot(ones(ws))

#画在相同的轴上(draw on the same axes)
def hold(param):
    pass


hold(True)
#绘制每个窗口(plot for every windows)
for w in WINDOWS[1:]:
    eval('plot('+w+'(ws) )')
#配置轴属性
axis([0,30,0,1.1])
legend(WINDOWS)
title("Smoothing windows")

subplot(212)
# 绘制原始信号
plot(x)
#绘制加噪信号
plot(xn)
for w in WINDOWS:
    plot(smooth(xn,10,w))
#为每个图添加图例
l=['original signal','signal with noise']
l.extend(WINDOWS)
legend(l)

title('Smoothed signal')

show()

运行测试:

2.12 真实数据的噪声平滑处理_第2张图片
可以看出窗口算法是如何影响噪声信号的。上面的图形显示了窗口算法,下面的图形显示了每一个相应的结果,包括原始信号、添加了噪声的信号和经过每个算法平滑处理过的信号

你可能感兴趣的:(Python数据可视化,scipy,python,numpy)