2013-05-01 6 views
1

벡터가 v = [NaN NaN 1 2 3 4 NaN NaN NaN 4 5 6]인데 각 연속 블록의 숫자 평균이 NaN이 아니라고 가정합니다. MATLAB에서 효율적인 방법은 무엇입니까? (물론, 실제 벡터이 예보다 훨씬 큰 무언가이다.)MATLAB에서 벡터의 블록 평균을 계산

답변

4

다음은 Image Processing Toolbox가 필요없는 벡터화 된 솔루션입니다.

는 귀하의 의견이 약간 더 복잡한 (나는 가장자리 케이스 포함)입니다 가정 :

v = [NaN NaN 1 2 3 4 NaN NaN NaN 4 5 6 NaN 3 NaN 3 4] 

% Index non NaNs 
nonNaN  = ~isnan(v(:)); 

% Find the beginning of a sequence and the element after the end 
subs  = diff([0; nonNaN]); 
start  = subs == 1; 
ends  = subs == -1; 
% Start labeling sequences progressively 
subs(start) = 1:nnz(start); 
subs(ends) = -(1:nnz(ends)); 
% Expand the labeling 
subs  = cumsum(subs); 

% Use accumarray 
accumarray(subs(nonNaN), v(nonNaN),[],@mean) 
+0

나는'accumarray'가 갈 방법이라고 생각합니다. – Justin

+0

감사합니다.'cumsum'을 매우 영리하게 사용합니다. 또한'accumarray '에 감사드립니다. 나는 오랫동안 이와 같은 명령을 찾고있었습니다. – passerby51

+0

이 아마도 가장 효율적인 솔루션 일 것입니다. +1 – bla

1

이 충분히 효율적입니다 경우에 당신이 볼 수

나는이이보다 더 효율적으로 발견 긴 벡터 v에 대한 놀랍게도
b=bwlabel(isfinite(v)); 
m=zeros(1,max(b)); 
for n=1:max(b) 
    id=find(b==n); 
    m(n)=mean(v(id)); 
end 

논리적 인덱싱 옵션 mean(v(b==n)) ...

+0

감사를 bwlabel''을 가리키는 위해. – passerby51

+1

@ passerby51'bwlabel'과'accumarray'를 함께 사용할 수 있습니다. 0 인덱스를 버려야 할 것입니다. – Justin

+0

@jucestain, yes'accumarray'는이 문제를 다루는 좋은 방법 인 것 같습니다. 0을 던지기 위해서, 이것은'subs = b (b ~ = 0)'으로 충분할 것입니다. – passerby51

관련 문제