Loop with several conditions

2 visualizaciones (últimos 30 días)
Julie Møller
Julie Møller el 27 de Abr. de 2021
Comentada: Julie Møller el 28 de Abr. de 2021
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 comentario
DGM
DGM el 27 de Abr. de 2021
Editada: DGM el 27 de Abr. de 2021
I don't really see this as a multiple conditions problem. You'd find days without Tdata, place zeros (or other dummy data) accordingly. Once all days have datapoints, extract only the rows with non-NaN Tdata, and do interp1() on the whole thing.

Iniciar sesión para comentar.

Respuesta aceptada

DGM
DGM el 27 de Abr. de 2021
Editada: DGM el 27 de Abr. de 2021
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.
  1 comentario
Julie Møller
Julie Møller el 28 de Abr. de 2021
Thank you very much, your code does exactly what I requested! I had difficulties thinking my way through the problem and what commands would be smart to use. I can follow your code, and of course it seems simpler now, thank you for your time :-)

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Time Series Events en Help Center y File Exchange.

Etiquetas

Community Treasure Hunt

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

Start Hunting!

Translated by