2016-12-15 91 views
1

我有一個大的numpy陣列,尺寸爲[1]。我想找出一種「羣體平均值」。更具體地說,組數的平均數?

讓我的陣列爲[1,2,3,4,5,6,7,8,9,10]並讓我的group_size3。因此,我將平均前三個元素,第4到第6元,7日至9元,在這種情況下得到平均剩餘的元素(只有1 - [2, 5, 8, 10]不用說,我需要一個量化的實施

最後,我的目的是減少在嘈雜的圖形點的數量,以平滑了有很多的振盪的一種普遍現象。有沒有正確辦法做到這一點?我想回答這兩個問題,萬一他們有一個不同的答案。謝謝!

+1

來平滑一個嘈雜的圖案,則更有可能要滾動平均值(即,平均元件0-2,然後1-3,然後2-4,等,因此平均值重疊)。熊貓圖書館有這樣的功能內置。 – BrenBarn

+0

是的,謝謝你,滾動平均值給我一個很好的結果。儘管如此,我也很想知道第一個答案! – martianwars

回答

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] 
+0

謝謝,作爲一個便箋,你能否回答第一個問題呢? – martianwars

2

爲了解決該組平均,下面列出的兩種方法。

方法1:基於斌求和平均

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

+0

謝謝@Divakar!你能否添加一些平滑嘈雜圖形的技巧? – martianwars

+0

@martianwars新增了對它的評論。 – Divakar

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