Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Brain teaser - filtering algorithm using moving averages

I have a 1 second dataset of 86400 wind speed (WS) values in Matlab and need assistance in filtering it. It requires a certain level of cleverness.

If the average WS exceeds:

  • 25m/s in a 600s time interval
  • 28m/s in a 30s time interval
  • 30m/s in a 3 s time interval

If any of these parameters are met, the WS is deemed 'invalid' until the average WS remains below 22m/s in a 300 s time interval.

Here is what I have for the 600 second requirement. I do a 600 and 300 second moving average on the data contained in 'dataset'. I filter the intervals from the first appearance of an average 25m/s to the next appearance of a value below 22m/s as 'NaN'. After filtering, I will do another 600 second average, and the intervals with values flagged with a NaN will be left a NaN.

i.e.

Rolling600avg(:,1) = tsmovavg(dataset(:,2), 's', 600, 1);

Rolling300avg(:,1) = tsmovavg(dataset(:,2), 's', 300, 1);

a = find(Rolling600avg(:,2)>25)

b = find(Rolling300avg(:,2)<22)

dataset(a:b(a:find(b==1)),2)==NaN; %?? Not sure

This is going to require a clever use of 'find' and some indexing. Could someone help me out? The 28m/s and 30m/s filters will follow the same method.

like image 918
user1854628 Avatar asked Nov 26 '12 20:11

user1854628


1 Answers

If I follow your question, one approach is to use a for loop to identify where the NaNs should begin and end.

m = [19 19 19 19 28 28 19 19 28 28 17 17 17 19 29 18 18 29 18 29]; %Example data
a = find(m>25);
b = find(m<22); 
m2 = m;
% Use a loop to isolate segments that should be NaNs;
for ii = 1:length(a)
     firstNull = a(ii) 
     lastNull  = b( find(b>firstNull,1) )-1 % THIS TRIES TO FIND A VALUE IN B GREATER THAN A(II)
     % IF THERE IS NO SUCH VALUE THEN NANS SHOULD FILL TO THE END OF THE VECTOR
     if isempty(lastNull), 
         lastNull=length(m); 
     end 
     m2(firstNull:lastNull) = NaN
end

Note that this only works if tsmovavg returns an equal length vector as the one passed to it. If not then it's trickier and will require some modifications.

There's probably some way of avoiding a for loop but this is a pretty straight forward solution.

like image 53
jerad Avatar answered Nov 03 '22 20:11

jerad