2014-05-23 159 views
0

我發現另一個人詢問同一個問題,但答案不適用於任意長度的向量。在matlab中對任意長度向量進行移動平均

Averaging every n elements of a vector in matlab

問題:

X = [1:12]; y =%平均操作; 操作結束後, y = [2 2 2 5 5 8 8 8 11 11 11] 因此,生成的向量具有相同的大小,並且每3個值的跳躍平均值將替換用於生成平均值的值即1 2 3被三個值的平均值替代,2 2 2)。有沒有辦法做到這一點沒有循環?

但是,如果向量x是任意的(在我的情況下,例如500001),並且您想要任意縮放它,例如平均超過1000個樣本......是否沒有準備好matlab函數呢,這似乎是一個標準問題?

+1

把它做成長度爲5001000的向量,然後按照鏈接中的代碼,然後切斷結束。讓這個任意長度的工作不應該太難。 –

+0

您應該指定您希望發生的數據系列中沒有全部1000個樣本的剩餘部分。解決方案取決於此。 – Trilarion

回答

1

以下代碼爲您提供任何過濾長度爲n和任何數據長度爲N的「跳躍平均值」。爲使代碼正常工作,N必須被n整除。 (跳平均是不是一個標準的術語。我做這件事。對我來說,這個過濾器就像是一個「移動平均」,但不是連續移動的,你跳。)

x = 1:20;  % so N=length(x) is 20 
n = 5;  % filter length 
xx = reshape(x,n,[]); 
yy = sum(xx,1)./size(xx,1); 
y = reshape(repmat(yy, size(xx,1),1),1,[]); 

如果N是21,例如,那麼N不能被n除盡,並且此代碼將返回一個錯誤。更深層次的原因是在這種情況下如何處理邊緣沒有明顯的方法。既然你有很多的數據點,我只想把最後幾個數據丟掉。

x = 1:21;  
N = length(x); 
throw_away = mod(N,n)-1; 
x(end-throw_away:end) = [] 
xx = reshape(x,n,[]); 
yy = sum(xx,1)./size(xx,1); 
y = reshape(repmat(yy, size(xx,1),1),1,[]); 

這應該會給你你想要的結果。但是,我建議你完全拋棄這種方法,而是使用標準函數來平滑數據。您可以使用built-in digital filtering function,也可以使用卷積實現簡單移動平均濾波器。下面是兩個代碼:

x = 1:21;  
n=5; 
y1 = filter(ones(1,n)/n, 1, x); 
y2 = conv(x, ones(1,n)/n,'valid'); 

如果你看看你Y1會發現,它落後於輸入數據,這是數字濾波器的標準屬性後面。這種「相位延遲」是n/2分。

如果你看看y2,你會注意到矢量比輸入矢量短(n-1)。這是因爲這個特定的呼叫只會返回那些可以完全計算移動平均值的值。如你所見,有很多不同的方式來處理邊緣的數據,但在現實世界中,這些邊緣情況很少有關係。

+0

謝謝!我沒有意識到可以使用過濾器功能。現在代碼更簡單,更整齊。 – Erik