필터 지우기
필터 지우기

How to average sequential chunks of one vector based on the criteria of another

조회 수: 2 (최근 30일)
Good Afternoon,
Working with a time vector, EChr (values 0-23.5, in 0.5 increments), and another vector, A, I need to average the values of A around each midnight (i.e., 0.0), leaving the rest of the values NaNed.
My code (below) would be fine if EChr didn't have breaks in the half-hour sequence. This is not the case.
How can I code this to bracket chunks surrounding each midnight (i.e., 0.0) based on the actual values of EChr, not the indices of EChr?
Lastly, this will surely get me an out of bounds error sooner or later. How can this be avoided?
for i=1:length(EChr)
if EChr(i)==0.0 % 0.0= midnight
A(i)=nanmean(A(i-4:i+6)); % 0.5 hour steps; 2 hours before midnight and 3 hours after midnight (i.e., 22.0-3.0)
end
end

채택된 답변

Alain Kuchta
Alain Kuchta 2017년 5월 15일
Since your time vector is not guaranteed to follow a regular pattern, I think you need to use an iterative approach and perform the averaging manually.
The following code works by accumulating a sum when in an appropriate "region" of the data and then calculates the mean when exiting the region. The averages and NaNs are then inserted after the loop using logical indexing.
The approach does not assume any number of samples on either side of midnight. Getting the averageCount based on the number of midnights lets us be sure we've calculated all the averages when the loop is finished.
accumulated = 0;
rollingCount = 0;
averageCount = sum(EChr == 0);
averageCounter = 1;
averages = zeros(1, averageCount);
accumulating = false;
for i=1:numel(EChr)
if EChr(i) <= 3.0 || EChr(i)>= 22.0
accumulated = accumulated + A(i);
rollingCount = rollingCount + 1;
accumulating = true;
elseif accumulating == true
averages(averageCounter) = accumulated / rollingCount;
averageCounter = averageCounter + 1;
accumulated = 0;
rollingCount = 0;
accumulating = false;
else
%do nothing
end
end
% Edge Case - Was still accumulating at end of loop,
% and there is still an average left to compute
if accumulating && averageCounter < averageCount + 1
averages(averageCounter) = accumulated / rollingCount;
averageCounter = averageCounter + 1;
end
A(EChr==0) = averages;
A(EChr~=0) = NaN;
  댓글 수: 1
balsip
balsip 2017년 5월 16일
Very clever, Alain. Thank you for your time. I'll report back on this if any issues arise, but so far it looks to be doing the trick!

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Matched Filter and Ambiguity Function에 대해 자세히 알아보기

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by