numpy数组的平均值?

时间:2016-12-15 06:07:15

标签: python numpy matplotlib

我有一个大的numpy数组,维度为[1]。我想找出一种"组平均值"。更具体地说,

让我的数组为[1,2,3,4,5,6,7,8,9,10],让我的group_size3。因此,我将平均前三个元素,第4到第6个元素,第7个到第9个元素,并平均其余元素(在这种情况下只有1个 - [2, 5, 8, 10]。不用说,我需要一个矢量化实施

最后,我的目的是减少噪声图中的点数,以平滑具有大量振荡的一般模式。是否有正确的方式来执行此操作?我希望得到两个问题的答案,以防他们有不同的答案。谢谢!

3 个答案:

答案 0 :(得分:2)

良好的平滑功能是kernel convolution。它的作用是在一个移动窗口中将一个小数组乘以较大的数组。

假设您选择了1/3 * [1,1,1]的标准平滑内核并将其应用于数组(内核需要奇数编号并进行规范化)。让我们将其应用于[1,2,2,7,3,4,9,4,5,6]

开始的核心中心位于第一个2。然后它平均自己和它的邻居,然后继续前进。结果是这样的: [1.67, 3.67, 4.0, 4.67, 5.33, 5.67, 6.0, 5.0]

请注意,数组缺少第一个和最后一个元素。

您可以使用numpy.convolve执行此操作,例如:

import numpy as np
a = np.array([[1,2,2,7,3,4,9,4,5,6]])
k = np.array([1,1,1])/3
smoothed = np.convolve(x, k, 'valid')

这样做的结果是您的中心值使用其邻居的值进行平滑处理。您可以通过增加卷积内核来改变卷积内核,例如[1,1,1,1,1]/5,或者给它一个高斯,这将比中心成员更多地强调中心成员。阅读维基百科文章。

修改

当问题要求时,这可以获得块平均值:

import numpy as np

a = [1,2,3,4,5,6,7,8,9,10]
size = 3

new_a = []
i = 0
while i < len(a):
    val = np.mean(a[i:i+3])
    new_a.append(val)
    i+=size

print(new_a)

[2.0, 5.0, 8.0, 10.0]

答案 1 :(得分:2)

要解决群体平均问题,下面列出了两种方法。

方法#1:基于Bin的求和和平均值

In [77]: a
Out[77]: array([74, 48, 92, 40, 35, 38, 20, 69, 82, 37])

In [78]: N = 3 # Window size

In [79]: np.arange(a.size)//N # IDs for binning with bincount
Out[79]: array([0, 0, 0, 1, 1, 1, 2, 2, 2, 3])

In [84]: np.bincount(np.arange(a.size)//N,a)/np.bincount(np.arange(a.size)//N)
Out[84]: array([ 71.33333333,  37.66666667,  57.        ,  37.        ])

方法#2:基于平均值的切片和重塑

In [134]: limit0 = N*(a.size//N)

In [135]: out = np.zeros((a.size+N-1)//N)

In [136]: out[:limit0//N] = a[:limit0].reshape(-1,N).mean(1)

In [137]: out[limit0//N:] = a[limit0:].mean()

In [138]: out
Out[138]: array([ 71.33333333,  37.66666667,  57.        ,  37.        ])

为了平滑数据,我建议使用基本上是卷积平均值的MATLAB's smooth function ported to NumPy,并且应该与@Roman's post类似。

答案 2 :(得分:0)

真的,真的希望numpy.ma.MaskedArray.resize有效。这将允许一步回答这个问题。

因为它是

def groupAverage(arr,idx):
    rem=arr.size%idx
    if rem==0:
       return np.mean(arr.reshape(idx,-1),index=0) 
    else:
        newsize=arr//size+1
        averages=np.mean(arr.resize(idx,newsize),index=0)
        averages[-1]*=(idx/rem)
        return averages