2017-08-21 61 views
5

Czy istnieje sposób na obliczenie średniej ruchomej w taki sposób, aby wartości na początku i na końcu tablicy były uśrednione z wartościami na przeciwnym końcu?Przenoszenie oznacza na okręgu

Na przykład, zamiast tego wyniku:

A=[2 1 2 4 6 1 1]; 
movmean(A,2) 
ans = 2.0 1.5 1.5 3.0 5 3.5 1.0 

Chcę otrzymać wektor [1.5 1.5 1.5 3 5 3.5 1.0], jako początkowy element tablicy 2 będzie uśredniona z elementem kończącym 1.

Odpowiedz

5

Uogólniając do dowolnego rozmiaru okna N, to w jaki sposób można dodać okrągłą zachowanie do movmean w drodze chcesz:

movmean(A([(end-floor(N./2)+1):end 1:end 1:(ceil(N./2)-1)]), N, 'Endpoints', 'discard') 

dla danego A i N = 2 dostaniesz:

ans = 

1.5000 1.5000 1.5000 3.0000 5.0000 3.5000 1.0000 
+0

słodki! nie pomyślałem o tym. dzięki! – shamalaia

2

splot oferuje jedne ładny sposoby robienia tego. Może być jednak konieczne nieznaczne zmodyfikowanie danych wejściowych, jeśli zamierzasz tylko częściowo uśrednić końce (tzn. Pierwsza jest uśredniona z ostatnią w twoim przykładzie, ale ostatnia nie jest uśredniona dla pierwszej).

conv([A(end),A],[0.5 0.5],'valid') 

ans = 

    1.5000 1.5000 1.5000 3.0000 5.0000 3.5000 1.0000 

Uogólniony przypadek tutaj, na ruchomej średniej wielkości N jest:

conv(A([end-N+2:end, 1:end]),repmat(1/N,1,N),'valid') 
+0

Myślałem, że zrobię to w ten sposób. Ale w tym rozwiązaniu nie podobało mi się to, że wyjście ma różne wymiary. Również konwój, jeśli zamiast 2 wartości, średnio więcej. Oczywiście mogę przyciąć wyjście, ale zastanawiałem się, czy istnieje lepszy sposób na zrobienie tego. – shamalaia

+0

Widzę, dane wyjściowe mają poprawne wymiary dla 'conv', jeśli masz' 'valid'' flag, ale tak, gnovice's rozwiązanie pokazuje flagi 'movmean', aby uzyskać pożądany wynik. – informaton

+0

Zaktualizowałem swoją odpowiedź, aby pokazać uogólnioną formę dla 'conv' i wyjąłem odpowiedź' movmean', która jest lepiej opisana przez @gnovice. – informaton

2

dla dowolnego rozmiaru okna n, można użyć circular convolution z maską uśredniania zdefiniowany jako [1/n ... 1/n] (z n wpisów; w twoim przykładzie: n = 2):

result = cconv(A, repmat(1/n, 1, n), numel(A));