Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Python平均信号以消除噪声_Python_Signals_Signal Processing_Average - Fatal编程技术网

如何使用Python平均信号以消除噪声

如何使用Python平均信号以消除噪声,python,signals,signal-processing,average,Python,Signals,Signal Processing,Average,我正在实验室里用Arduino Mega 2560板做一个小项目。我想对三角形波的正斜率部分(上升)的信号(电压)求平均值,以尽可能地去除噪声。我的频率为20Hz,数据传输速率为115200位/秒(Arduino建议将最快的数据传输到计算机) 原始信号如下所示: 我的数据存储在一个文本文件中,每行对应一个数据点。由于我有数千个数据点,我希望一些平均值会使我的信号看起来更平滑,并在这种情况下形成一条接近完美的直线。然而,其他实验条件可能会产生一个信号,在这个信号中,我可以沿着三角波的正斜率部

我正在实验室里用Arduino Mega 2560板做一个小项目。我想对三角形波的正斜率部分(上升)的信号(电压)求平均值,以尽可能地去除噪声。我的频率为20Hz,数据传输速率为115200位/秒(Arduino建议将最快的数据传输到计算机)

原始信号如下所示:

我的数据存储在一个文本文件中,每行对应一个数据点。由于我有数千个数据点,我希望一些平均值会使我的信号看起来更平滑,并在这种情况下形成一条接近完美的直线。然而,其他实验条件可能会产生一个信号,在这个信号中,我可以沿着三角波的正斜率部分有一些特征,比如负峰值,我绝对需要能够在我的平均信号上看到这个特征

我是Python初学者,所以我可能没有理想的方法来这么做,我的代码对你们大多数人来说可能很糟糕,但我仍然希望得到你们的提示/想法,如何改进我的信号处理代码,通过平均信号来实现更好的噪声消除

#!/usr/bin/python
import matplotlib.pyplot as plt
import math

# *** OPEN AND PLOT THE RAW DATA ***
data_filename = "My_File_Name"
filepath = "My_File_Path" + data_filename + ".txt"

# Open the Raw Data
with open(filepath, "r") as f:
    rawdata = f.readlines()

# Remove the \n     
rawdata = map(lambda s: s.strip(), rawdata)

# Plot the Raw Data
plt.plot(rawdata, 'r-')
plt.ylabel('Lightpower (V)')
plt.show()

# *** FIND THE LOCAL MAXIMUM AND MINIMUM
# Number of data points for each range 
datarange = 15 # This number can be changed for better processing
max_i_range = int(math.floor(len(rawdata)/datarange))-3

#Declare an empty lists for the max and min
min_list = []
max_list = []

min_list_index = []
max_list_index = []

i=0

for i in range(0, max_i_range):
    delimiter0 = i * datarange
    delimiter1 = (i+1) * datarange
    delimiter2 = (i+2) * datarange
    delimiter3 = (i+3) * datarange

    sumrange1 = sum(float(rawdata[i]) for i in range(delimiter0, delimiter1 + 1))
    averagerange1 = sumrange1 / len(rawdata[delimiter0:delimiter1])
    sumrange2 = sum(float(rawdata[i]) for i in range(delimiter1, delimiter2 + 1))
    averagerange2 = sumrange2 / len(rawdata[delimiter1:delimiter2])
    sumrange3 = sum(float(rawdata[i]) for i in range(delimiter2, delimiter3 + 1))
    averagerange3 = sumrange3 / len(rawdata[delimiter2:delimiter3])

    # Find if there is a minimum in range 2
    if ((averagerange1 > averagerange2) and (averagerange2 < averagerange3)):
        min_list.append(min(rawdata[delimiter1:delimiter2])) # Find the value of all the minimum 

        #Find the index of the minimum
        min_index = delimiter1 + [k for k, j in enumerate(rawdata[delimiter1:delimiter2]) if j == min(rawdata[delimiter1:delimiter2])][0] # [0] To use the first index out of the possible values
        min_list_index.append(min_index)


    # Find if there is a maximum in range 2
    if ((averagerange1 < averagerange2) and (averagerange2 > averagerange3)):
        max_list.append(max(rawdata[delimiter1:delimiter2])) # Find the value of all the maximum

        #Find the index of the maximum
        max_index = delimiter1 + [k for k, j in enumerate(rawdata[delimiter1:delimiter2]) if j == max(rawdata[delimiter1:delimiter2])][0] # [0] To use the first index out of the possible values
        max_list_index.append(max_index)



# *** PROCESS EACH RISE PATTERN ***

# One rise pattern goes from a min to a max
numb_of_rise_pattern = 50 # This number can be increased or lowered. This will average 50 rise patterns

max_min_diff_total = 0

for i in range(0, numb_of_rise_pattern):
    max_min_diff_total = max_min_diff_total + (max_list_index[i]-min_list_index[i])

# Find the average number of points for each rise pattern
max_min_diff_avg = abs(max_min_diff_total / numb_of_rise_pattern)

# Find the average values for each of the rise pattern
avg_position_value_list = []


for i in range(0, max_min_diff_avg):

    sum_position_value = 0
    for j in range(0, numb_of_rise_pattern):

        sum_position_value = sum_position_value + float( rawdata[ min_list_index[j] + i ] )
    avg_position_value = sum_position_value / numb_of_rise_pattern

    avg_position_value_list.append(avg_position_value)


#Plot the Processed Signal
plt.plot(avg_position_value_list, 'r-')
plt.title(data_filename)
plt.ylabel('Lightpower (V)')
plt.show()
#/usr/bin/python
将matplotlib.pyplot作为plt导入
输入数学
#***打开并绘制原始数据***
data\u filename=“我的文件名”
filepath=“我的文件路径”+数据文件名+“.txt”
#打开原始数据
将open(filepath,“r”)作为f:
rawdata=f.readlines()
#删除\n
rawdata=map(lambda s:s.strip(),rawdata)
#绘制原始数据
plt.绘图(原始数据“r-”)
plt.ylabel(‘光功率(V)’)
plt.show()
#***找到局部最大值和最小值
#每个范围的数据点数量
datarange=15#可以更改此数字以更好地处理
max_i_range=int(数学层(len(rawdata)/datarange))-3
#为最大值和最小值声明空列表
最小列表=[]
最大值列表=[]
最小列表索引=[]
最大列表索引=[]
i=0
对于范围内的i(0,最大i_范围):
delimiter0=i*数据范围
delimiter1=(i+1)*数据范围
分隔符R2=(i+2)*数据范围
分隔符r3=(i+3)*数据范围
sumrange1=范围(delimiter0,delimiter1+1)中i的总和(浮点(原始数据[i]))
AveragerRange1=sumrange1/len(原始数据[delimiter0:delimiter1])
sumrange2=范围(delimiter1,delimiter2+1)中i的总和(浮点(原始数据[i]))
AveragerRange2=sumrange2/len(原始数据[delimiter1:delimiter2])
sumrange3=范围(分隔符r2,分隔符r3+1)中i的总和(浮点(原始数据[i]))
AveragerRange3=sumrange3/len(原始数据[delimiter2:delimiter3])
#查找范围2中是否有最小值
如果((averagerange1>averagerange2)和(averagerange2averagerange3)):
max_list.append(max(rawdata[delimiter1:delimiter2]))#查找所有最大值的值
#找到最大值的索引
max_index=delimiter1+[k代表k,j在枚举(rawdata[delimiter1:delimiter2])中,如果j==max(rawdata[delimiter1:delimiter2])][0]#[0]使用可能值中的第一个索引
max\u list\u index.append(max\u index)
#***处理每个上升模式***
#一个上升模式从最小到最大
上升模式的麻木=50#此数字可以增加或减少。这将平均增加50种模式
最大最小差异总计=0
对于范围内的i(0,上升模式的麻木):
max_min_diff_total=max_min_diff_total+(max_list_index[i]-min_list_index[i])
#找出每个上升模式的平均点数
最大最小差异平均值=绝对值(最大最小差异总值/上升模式的数值)
#找到每个上升模式的平均值
平均位置值列表=[]
对于范围内的i(0,最大最小差异平均值):
总和位置值=0
对于范围内的j(0,上升模式的麻木):
求和位置值=求和位置值+浮点(原始数据[最小列表索引[j]+i])
平均位置值=总位置值/上升模式的麻木值
平均位置值列表。追加(平均位置值)
#绘制处理后的信号
plt.绘图(平均位置值列表“r-”)
plt.title(数据\文件名)
plt.ylabel(‘光功率(V)’)
plt.show()
最后,处理后的信号如下所示:

我希望能有一条更直的线,但我可能错了。我相信我的代码中可能有很多缺陷,当然会有更好的方法来实现我想要的。我已经包括了一个文本文件的链接,其中包含一些原始数据,如果你们中有人想从中获得乐趣的话


更简单的方法可能是使用平滑函数,例如移动窗口平均值。使用pandas.Series中的滚动函数实现这一点非常简单。(仅显示501个点。)调整数值参数(窗口大小)以获得不同的平滑量

import pandas as pd
import matplotlib.pyplot as plt

# Plot the Raw Data
ts = rawdata[0:500]
plt.plot(ts, 'r-')
plt.ylabel('Lightpower (V)')

#    previous version
#    smooth_data = pd.rolling_mean(rawdata[0:500],5).plot(style='k')
#    changes to pandas require a change to the code as follows:
smooth_data = pd.Series(ts).rolling(window=7).mean().plot(style='k')
plt.show()

移动平均基本上是一个低通滤波器。因此,我们还可以使用SciPy的函数实现一个低通滤波器,如下所示:

import scipy.signal as signal

# First, design the Buterworth filter
N  = 3    # Filter order
Wn = 0.1 # Cutoff frequency
B, A = signal.butter(N, Wn, output='ba')
smooth_data = signal.filtfilt(B,A, rawdata[0:500])
plt.plot(ts,'r-')
plt.plot(smooth_data[0:500],'b-')
plt.show()

Butterworth过滤器方法来自,顺便说一句