Daywise differences in array
1 view (last 30 days)
Show older comments
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 Comments
Accepted Answer
dpb
on 8 Oct 2024
Edited: dpb
on 9 Oct 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 Comments
dpb
on 10 Oct 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
on 12 Oct 2024
Edited: dpb
on 12 Oct 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
...
More Answers (0)
See Also
Categories
Find more on Tables in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!