2013-08-04 2 views
1

이것은 이전 질문에 대한 후속 작업으로 here입니다. Oleg Komarov의 대답에 기초하여 나는 accumarray() 및 datevec()의 출력 구조를 사용하는 데이터의 평균 또는 합계를 매일, 매시간 등으로 얻는 작은 도구를 작성했습니다. 그것을 (아마 아주 잘 쓰여지지는 않았지만 그것은 나를 위해 일한다)을 보아도된다.MATLAB : n 분/시간/일 평균 시계열

지금 내가하고 싶은 것은 1 분, 1 시간, 1 일 등의 통계 대신 n 분, n 시간, n 일 등의 통계를 계산하는 기능을 추가하는 것입니다. 함수가 수행합니다. 나는 단순히 시간 벡터 t를 반복하는 대략적인 아이디어를 가지고있다. (내가 아름다운 accumarray()에 대해 배웠다면 이미했던 것처럼 될 것이다.) 그러나 나는 많은 것을해야한다는 것을 의미한다. 데이터 갭, 불균일 한 샘플링 시간 등에 대한 에러 검사

위에서 게시 한 예전 함수, 즉 여전히 accumarray를 사용하는 좀 더 우아하고 효율적인 접근법이 있는지 궁금합니다.() 및 datevec()를 사용하면 쉽습니다.

마지막 질문 인 here에서 가져온 샘플 데이터를 다운로드 할 수 있습니다. 이것들은 30 분 간격으로 샘플링되었으므로 내가 원하는 것은 가능한 한 예가 없이 6 시간 평균을 계산하는 것일 것입니다.은 간격이없고 항상 정확히 30 분으로 샘플링된다는 가정에 의존합니다.


는 예를 들어 0시 반이 0시 반에서의 간격에 대한 대표 (타임 스탬프와 함께 작지만 쉽게 고정 문제로부터 떨어져, 합리적으로 잘 작동하는, 내가 지금까지 함께 온 것입니다 0시 45분 - 내 옛 기능)하지만, 같은 문제가 앓고 :

[... 내 대답은 아래 ... 참조] 영감을 woodchips

감사합니다.

답변

1

나는 @Bas Swinckels 대답과 @woodchip의 코드가 위에 링크 된 부분을 사용하여 알아 냈다고 생각합니다. 정확하지 않은 것은 내가 좋은 코드라고 부르는 것이 아니라 일하고 합리적으로 빠릅니다.

function [ t_acc, x_acc, subs ] = ts_aggregation(t, x, n, target_fmt, fct_handle) 
% t is time in datenum format (i.e. days) 
% x is whatever variable you want to aggregate 
% n is the number of minutes, hours, days 
% target_fmt is 'minute', 'hour' or 'day' 
% fct_handle can be an arbitrary function (e.g. @sum) 
    t = t(:); 
    x = x(:); 
    switch target_fmt 
     case 'day' 
      t_factor = 1; 
     case 'hour' 
      t_factor = 1/24; 
     case 'minute' 
      t_factor = 1/(24 * 60); 
    end 
    t_acc = (t(1) : n * t_factor : t(end))'; 
    subs = ones(length(t), 1); 
    for i = 2:length(t_acc) 
     subs(t > t_acc(i-1) & t <= t_acc(i)) = i; 
    end 
    x_acc = accumarray(subs, x, [], fct_handle); 
end 

/편집 : 루프를 사용하는 훨씬 짧은 fnction으로 업데이트되었지만 이전 솔루션보다 빠릅니다.

2

accumarray을 사용하는 링크 된 방법은 간격이없는 균일 한 간격으로 측정을 시작하면 지나치게 복잡하고 너무 복잡합니다. 나는 벡터의 N 점의 평균을 계산하는 내 개인 도구 상자에서 다음과 같은 기능을 가지고 :

function y = blockaver(x, n) 
% y = blockaver(x, n) 
% input points are averaged over n points 
% always returns column vector 

if n == 1 
    y = x(:); 
else 
    nblocks = floor(length(x)/n); 
    y = mean(reshape(x(1:n * nblocks), n, nblocks), 1).'; 
end 

작품 꽤 잘위한 요소 N에 의해 ​​신속하고 더러운 데시 메이팅하지만 적절한 앤티 앨리어싱을 적용하지 않습니다 필터링. 중요한 경우 decimate을 사용하십시오.

+1

기능을 공유해 주셔서 감사합니다. 나중에 사용할 수 있도록 저장해 두었습니다. 그것은 내가 마음 속에 가지고 있었던 것에 가깝게 온다. 그러나 그것의 재사용의 사용은 조금 더 우아하다. 그러나, 당신은 이미'accumarray'가 내 경우에 우월한 이유에 대해 이미 언급했다. 나는 환경 데이터를 사용하며 슬프게도 완전하고 균일 한 간격을 가지지 않는다. 나는 이것을 언급해야했다. –