Daywise differences in array
1 Ansicht (letzte 30 Tage)
Ältere Kommentare anzeigen
Hello
I have the following time series
1982 5 1 3 25
1982 5 1 6 30
1982 5 1 12 35
1982 5 1 18 40
1982 5 2 0 45
1982 5 2 3 45
1982 5 2 6 50
1982 5 2 12 55
1982 5 2 18 55
1982 5 3 0 60
1982 5 3 3 65
1982 5 3 6 80
1982 5 3 12 90
1982 5 3 18 105
1982 5 4 0 115
1982 5 4 3 115
1982 5 4 6 115
1982 5 4 12 115
1982 5 4 18 115
1982 5 5 3 30
The first four columns show year, month, day and hour and the last column shows the 3-hourly rainfall. I wish to find out if the rainfall value at each 3-hourly time series is more than 30 mm within the next 24 hours. For example, the difference in rainfall value of 1982/5/1 at 3 hrs - 1982/5/2 at 3hrs should be greater than 30 mm. This I need to search for the entire series and locate the rows where the difference in rainfall values are more than 30 mm from its previous 24 hrour values. I am trying with caldays(1) but getting stuck for the end rows. Also, my approach ionvolves for loop, which is not efficient. Pls. help!
0 Kommentare
Akzeptierte Antwort
dpb
am 8 Okt. 2024
Bearbeitet: dpb
am 9 Okt. 2024
R=[1982 5 1 3 25
1982 5 1 6 30
1982 5 1 12 35
1982 5 1 18 40
1982 5 2 0 45
1982 5 2 3 45
1982 5 2 6 50
1982 5 2 12 55
1982 5 2 18 55
1982 5 3 0 60
1982 5 3 3 65
1982 5 3 6 80
1982 5 3 12 90
1982 5 3 18 105
1982 5 4 0 115
1982 5 4 3 115
1982 5 4 6 115
1982 5 4 12 115
1982 5 4 18 115
1982 5 5 3 30];
ttR=timetable(datetime(R(:,1:3))+hours(R(:,4)),R(:,5),'VariableNames',{'Rainfall'})
LastTime=ttR.Time(end);
t=[]; r=[];
for i=1:height(ttR)
nextDay=ttR.Time(i)+caldays(1);
%[ttR.Time(i) nextDay LastTime]
if nextDay>LastTime, break, end
% account for not accumulating globally as initially thought, Umar's solution
inDay=timerange(ttR.Time(i),nextDay); % indexing expression for 24hr period
%dRF=ttR.Rainfall(nextDay)-ttR.Rainfall(i); % amount difference at now+24hr
dRF=max(ttR.Rainfall(inDay))-ttR.Rainfall(i); % amount difference in 24hr accounting for rollover
%[ttR.Rainfall(i) ttR.Rainfall(nextDay) dRF];
if dRF>30
t=[t;ttR.Time(i)];
r=[r;dRF];
end
end
ttDRF=timetable(t,r,'VariableNames',{'24hr Rainfall'});
ttDRF.Properties.DimensionNames(1)={'Begin Date'};
ttDRF
I couldn't think of a really clever way to use indexting but I doubt this will be too bad unless your data file is really huge....although I did use dynamic reallocation here rather than allocating space for the temporaries.
11 Kommentare
dpb
am 10 Okt. 2024
"it should be nanmin(ttR.Rainfall(inDay)) as we are looking whether there is an increase of > 30, with max, we may discard a few events."
No, the min() won't find any events; the max() is returning the largest amount in the day in question; the delta computed is then the difference between it and the starting amount of the current 24hr period. The min will return the starting value for almost every 24hr period; only those in which the accumulator been reset will it find another value, and then the computed difference will turn out to be negative.
max() silently discards NaN anyway, so the nanmin, nanmax functions aren't required...
max([10;20;nan])
The potential issue about the reset period is still the one outlined above in the (probably rare) event that the second set of data produce a larger accumulated total than a first set within the 24 hr period after a reset.
One could check for that by finding the locations in the overall at which the sequential diff() of the rainfall is <0 and the checking if any of those dates are within the 24hr band after any of the returned exceedances.
dpb
am 12 Okt. 2024
Bearbeitet: dpb
am 12 Okt. 2024
"The potential issue about the reset period..."
Probably the cleanest solution is to add a little more logic...
...
inDay=timerange(ttR.Time(i),nextDay); % indexing expression for 24hr period
rfDay=ttR.Rainfall(inDay); % the accmulations in the 24hr
ixReset=find(diff(rfDay)<0);
if isempty(ixReset) % no reset in this period
dRF=rfdDay(end)-ttR.Rainfall(i); % amount difference in 24hr
else % there is a reset in this period
dRF=rfDay(ixReset)-ttR.Rainfall(i); % amount difference before reset
end
...
The above does the comparison to the period before the reset; the question is then one of a definition of what event(s) are actually wanted --the maximum total in the 24hr period would also include the amout after the reset, if any, in which case one would need the total of the two maxima in the period.
That would be more like
...
ixReset=find(diff(rfDay)<0);
if isempty(ixReset)
dRF=rfdDay(end)-ttR.Rainfall(i);
else
dRF=rfDay(ixReset)-ttR.Rainfall(i)+rfdDay(end); % amount before and after reset
end
...
Weitere Antworten (0)
Siehe auch
Kategorien
Mehr zu Tables finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!