简体   繁体   English

Python中数组的移动平均值

[英]Moving average of an array in Python

I have an array where discreet sinewave values are recorded and stored. 我有一个数组,其中记录和存储谨慎的正弦波值。 I want to find the max and min of the waveform. 我想找到波形的最大值和最小值。 Since the sinewave data is recorded voltages using a DAQ, there will be some noise, so I want to do a weighted average. 由于正弦波数据是使用DAQ记录的电压,因此会有一些噪声,因此我想进行加权平均。 Assuming self.yArray contains my sinewave values, here is my code so far: 假设self.yArray包含我的正弦波值,这是我的代码到目前为止:

filterarray = []
filtersize = 2
length = len(self.yArray)
for x in range (0, length-(filtersize+1)):
   for y in range (0,filtersize):
      summation = sum(self.yArray[x+y])
      ave = summation/filtersize
      filterarray.append(ave)

My issue seems to be in the second for loop, where depending on my averaging window size (filtersize), I want to sum up the values in the window to take the average of them. 我的问题似乎是在第二个for循环中,根据我的平均窗口大小(filtersize),我想总结窗口中的值以取其平均值。 I receive an error saying: 我收到一条错误说:

summation = sum(self.yArray[x+y])
TypeError: 'float' object is not iterable

I am an EE with very little experience in programming, so any help would be greatly appreciated! 我是一名EE,在编程方面经验很少,所以任何帮助都将不胜感激!

The other answers correctly describe your error, but this type of problem really calls out for using numpy. 其他答案正确地描述了您的错误,但这种类型的问题确实需要使用numpy。 Numpy will run faster, be more memory efficient, and is more expressive and convenient for this type of problem. Numpy 运行速度更快,内存效率更高,并且对于此类问题更具表现力和便利性。 Here's an example: 这是一个例子:

import numpy as np
import matplotlib.pyplot as plt

# make a sine wave with noise
times = np.arange(0, 10*np.pi, .01)
noise = .1*np.random.ranf(len(times))
wfm = np.sin(times) + noise

# smoothing it with a running average in one line using a convolution
#    using a convolution, you could also easily smooth with other filters
#    like a Gaussian, etc.
n_ave = 20
smoothed = np.convolve(wfm, np.ones(n_ave)/n_ave, mode='same')

plt.plot(times, wfm, times, -.5+smoothed)
plt.show()

在此输入图像描述

If you don't want to use numpy, it should also be noted that there's a logical error in your program that results in the TypeError . 如果您不想使用numpy,还应注意程序中存在导致TypeError的逻辑错误。 The problem is that in the line 问题是在线

summation = sum(self.yArray[x+y])

you're using sum within the loop where your also calculating the sum. 你在循环中使用sum ,你也计算总和。 So either you need to use sum without the loop, or loop through the array and add up all the elements, but not both (and it's doing both, ie , applying sum to the indexed array element, that leads to the error in the first place). 所以要么你需要在没有循环的情况下使用sum ,要么循环遍历数组并将所有元素相加,但不是两者兼而有(而且它同时执行两者, 对索引数组元素应用sum ,导致第一个中的错误地点)。 That is, here are two solutions: 也就是说,这里有两个解决方案:

filterarray = []
filtersize = 2
length = len(self.yArray)
for x in range (0, length-(filtersize+1)):
    summation = sum(self.yArray[x:x+filtersize]) # sum over section of array
    ave = summation/filtersize
    filterarray.append(ave)

or 要么

filterarray = []
filtersize = 2
length = len(self.yArray)
for x in range (0, length-(filtersize+1)):
    summation = 0.
    for y in range (0,filtersize):
        summation = self.yArray[x+y]
    ave = summation/filtersize
    filterarray.append(ave)

self.yArray[x+y] is returning a single item out of the self.yArray list. self.yArray[x+y]self.yArray列表中返回单个项目。 If you are trying to get a subset of the yArray , you can use the slice operator instead: 如果您尝试获取yArray的子集,则可以使用切片运算符:

summation = sum(self.yArray[x:y])

to return an iterable that the sum builtin can use. 返回内置sum可以使用的迭代。

A bit more information about python slices can be found here (scroll down to the "Sequences" section): http://docs.python.org/2/reference/datamodel.html#the-standard-type-hierarchy 有关python切片的更多信息可以在这里找到(向下滚动到“序列”部分): http//docs.python.org/2/reference/datamodel.html#the-standard-type-hierarchy

You could use numpy, like: 你可以使用numpy,如:

import numpy
filtersize = 2
ysums = numpy.cumsum(numpy.array(self.yArray, dtype=float))
ylags = numpy.roll(ysums, filtersize)
ylags[0:filtersize] = 0.0
moving_avg = (ysums - ylags) / filtersize

Your original code attempts to call sum on the float value stored at yArray[x+y] , where x+y is evaluating to some integer representing the index of that float value. 您的原始代码尝试在存储在yArray[x+y]的浮点值上调用sum,其中x+y正在计算表示该float值的索引的某个整数。

Try: summation = sum(self.yArray[x:y]) 尝试: summation = sum(self.yArray[x:y])

Indeed numpy is the way to go. 确实numpy是要走的路。 One of the nice features of python is list comprehensions, allowing you to do away with the typical nested for loop constructs. python的一个很好的特性是列表推导,允许你去掉典型的嵌套for循环结构。 Here goes an example, for your particular problem... 这是一个例子,针对您的特定问题......

import numpy as np
step=2
res=[np.sum(myarr[i:i+step],dtype=np.float)/step for i in range(len(myarr)-step+1)]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM