Info

Cette question est clôturée. Rouvrir pour modifier ou répondre.

Briain teaser - Filtering for particular algorithm

1 vue (au cours des 30 derniers jours)
Braden
Braden le 26 Nov 2012
Clôturé : MATLAB Answer Bot le 20 Août 2021
I have a 1 second dataset of 86400 wind speed (WS) values 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.

Réponses (1)

Walter Roberson
Walter Roberson le 26 Nov 2012
T = cumsum(dataset(:,2));
Rolling600avg = (T(601:end) - T(1:end-600)) ./ 600;
Rolling300avg = (T(301:end) - T(1:end-300)) ./ 300;
Rolling3avg = (T(4:end) - T(1:end-3)) ./ 3;
valid = true(1, size(dataset,1));
valid(601:end) = Rolling600avg < 25;
valid(301:end) = valid(301:end) & (Rolling300avg < 38);
valid(4:end) = valid(4:end) & (Rolling3avg < 30);
dataset(~valid) = NaN;
  6 commentaires
Braden
Braden le 26 Nov 2012
Yes, after the WS has exceeded one of those 3 parameters, it must remain below 22m/s for a 300s time interval to be considered valid again.
Braden
Braden le 26 Nov 2012
Modifié(e) : Braden le 26 Nov 2012
This might work - the for loops are clunky but I think it does the trick.
[dataset = wblrnd(15,2,100000,1);
m1 = tsmovavg(dataset, 's', 300, 1);
m2 = tsmovavg(dataset, 's', 600, 1);
a = find(m1<22);
b = find(m2>25);
m21 = m2;
% Use a loop to isolate segments that should be NaNs;
for ii = 1:length(b)
firstNull = b(ii)
lastNull = a( find(a>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(m2);
end
m21(firstNull:lastNull) = NaN;
end
m3 = tsmovavg(dataset, 's', 30, 1);
c = find(m3>28);
m22 = m2;
for ii = 1:length(c)
firstNull = c(ii)
lastNull = a( find(a>firstNull,1) )-1
if isempty(lastNull),
lastNull=length(m2);
end
m22(firstNull:lastNull) = NaN;
end
m4 = tsmovavg(dataset,'s',3,1);
d = find(m4>30);
m23 = m2;
for ii = 1:length(d)
firstNull = d(ii)
lastNull = a( find(a>firstNull,1) )-1 %
if isempty(lastNull);
lastNull=length(m2);
end
m23(firstNull:lastNull) = NaN;
end
mfinal = m2(~isnan(m21)&~isnan(m22)&~isnan(m23));

Cette question est clôturée.

Community Treasure Hunt

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

Start Hunting!

Translated by