Loop with several conditions
2 次查看(过去 30 天)
显示 更早的评论
I struggle with making a loop containing several conditions at once.
I have a matrix consisting of days (1st column), hours (2nd column) and a temperature value (3rd column). The total length of the matrix is (183 days x 24 hours =) 4392. Some days have no temp. value and other days have two temp. values.
All NaN-values should be found using linear interpolation, however some conditions apply:
If a day has two values e.g. day 61 (hour 6 and 16) (see screenshot (1)), the values for the hours in between (hour 7 to 15) is found by linear interpolation.
The values for day 61 before hour 6 and after hour 16 are also found by linear interpolation. The values before hour 6 is depending on day 60 having two values or not, and the same applies for the values after hour 16 that is then depending on day 62 having two values or not.
Day 60 does not have two values assigned (see screenshot (2)) and the way I need the interpolation to be done for the values before hour 6 is that a zero should be assigned for the hour located 12 hours before hour 6 (being day 60 hour 18) and then linear interpolation should be done for the 11 hours in between (hour 19 to 5).
On the other hand, day 62 has a value assigned at hour 3 (and 13) (see screenshot (3)), whereby the values between day 61 hour 16 and day 62 hour 3 need to be linearly interpolated between the corresponding values.
However, if day 62 had no values assigned, a zero should be assigned to the hour located 12 hours ahead of day 61 hour 16 and the values for the 11 hours in between should then be linearly interpolated as for the 12 hours before days 61 hour 6.
If several adjacent days have no values assigned, they should be zero. So, the values before day 60 hour 18 should be zeros until another value appears which happens to be at day 58 hours 24. In this case, zeros should then only be assigned until day 59 hour 12 as the same principle with the 12 hours ahead of day 58 hour 24 applies.
And so on and so forth for all hours of the 183 days.
I really struggle with making a loop containing all these conditions.. I hope someone can help me figuring it out!
If you have difficulties understanding the conditions, don’t hesitate to ask and I will try to elaborate further.
/Julie
1 个评论
采纳的回答
DGM
2021-4-27
编辑:DGM
2021-4-27
Maybe this is a start.
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% build example data
A = zeros([240 3]);
for d=1:10
A(24*(d-1)+(1:24),1) = 60+(d-1);
A(24*(d-1)+(1:24),2) = 1:24;
A(24*(d-1)+(1:24),3) = NaN;
if any((d-1)==[1 2 4 5 9])
A(24*(d-1)+[5 17],3) = rand(2,1);
end
end
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% show initial datapoints
plot(A(:,1)+(A(:,2)-1)/24,A(:,3),'bo'); hold on; grid on
daylist = unique(A(:,1));
hassamples = ismember(daylist,unique(A(~isnan(A(:,3)),1)))'
firstzero = [0 -diff(hassamples)]==1;
lastzero = [diff(hassamples) 0]==1;
needsfirst = daylist(firstzero) % days which need first sample
for d=1:numel(needsfirst)
idxp = find(A(:,1)==(needsfirst(d)-1)); % rows corresponding to prior day
lastdatapointhour = find(~isnan(A(idxp,3)),1,'last');
A(idxp(lastdatapointhour)+12,3) = 0; % insert sample
end
needssecond = daylist(lastzero) % days which need second sample
for d=1:numel(needssecond)
idxn = find(A(:,1)==(needssecond(d)+1)); % rows corresponding to next day
nextdatapointhour = find(~isnan(A(idxn,3)),1,'first');
A(idxn(nextdatapointhour)-12,3) = 0; % insert sample
end
T = A(:,3); % extract T data
xf = 1:numel(T);
x = xf(~isnan(T)); % strip NaN samples
T = T(~isnan(T));
% interpolate, using 0 for extrapolated values at ends
% adjust as needed
A(:,3) = interp1(x,T,xf,'linear',0);
% show interpolated data
plot(A(:,1)+(A(:,2)-1)/24,A(:,3));
It might be faster to strip NaNs first, allowing work on smaller arrays, but I chose to do it this way instead.
更多回答(0 个)
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Time Series Events 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!