Improve part of code using a loop

2 views (last 30 days)
I have an annual table X, where I want to calculate the five maximum values for each month. My code works but I need to also apply it for other variables so I am wondering how to shrink it a bit using a loop. So far i splitted the initial annual table (X) into months like this:
X_January = table(Dates{1,1},X{1,1});
X_February = table(Dates{2,1},X{2,1});
X_March = table(Dates{3,1},X{3,1});
X_April = table(Dates{4,1},X{4,1});
X_May = table(Dates{5,1},X{5,1});
X_June = table(Dates{6,1},X{6,1});
X_July = table(Dates{7,1},X{7,1});
X_August = table(Dates{8,1},X{8,1});
X_September = table(Dates{9,1},X{9,1});
X_October = table(Dates{10,1},X{10,1});
X_November = table(Dates{11,1},X{11,1});
X_December = table(Dates{12,1},X{12,1});
%Max 5 values for January
[Col,idx] = maxk(X_January{:,1},5);
T= X_January(idx,:)
Any ideas how to make a loop?
  2 Comments
Dyuman Joshi
Dyuman Joshi on 4 Feb 2023
Edited: Dyuman Joshi on 4 Feb 2023
How do you want to store your final output?
All values in a numeric array (12x5 or 5x12 )? If otherwise, please specify.
Ancalagon8
Ancalagon8 on 4 Feb 2023
@Dyuman Joshi Yes, all values in a numeric array (12X5).

Sign in to comment.

Accepted Answer

Star Strider
Star Strider on 4 Feb 2023
One approach —
date_time = (datetime('01-Jan-2023') : caldays(1) : datetime('31-Dec-2023')).';
Values = randn(numel(date_time), 5);
T1 = [table(date_time) array2table(Values)]
T1 = 365×6 table
date_time Values1 Values2 Values3 Values4 Values5 ___________ ________ ________ ________ _________ _________ 01-Jan-2023 -0.47138 0.78525 0.15011 0.83276 -0.59465 02-Jan-2023 -0.71248 -1.1215 0.2873 -0.07 0.48487 03-Jan-2023 1.4347 1.3957 -0.86495 0.38031 -1.3195 04-Jan-2023 0.90204 0.22882 0.52142 0.16887 -0.5348 05-Jan-2023 -0.52903 0.25618 1.0727 -1.0713 -1.1119 06-Jan-2023 0.41189 0.47979 -0.51813 -1.2685 1.2286 07-Jan-2023 -1.7744 -0.62537 -0.49037 -0.30792 -1.0039 08-Jan-2023 2.4883 -1.7341 0.48573 0.21777 -1.5177 09-Jan-2023 -0.97144 -0.19991 0.50003 -0.78522 -0.098178 10-Jan-2023 1.7618 0.17462 0.083165 -1.3276 0.80792 11-Jan-2023 -0.21396 -0.42347 0.69142 0.30005 0.16739 12-Jan-2023 1.2937 2.0955 -0.52163 -0.023047 1.8627 13-Jan-2023 0.025689 -1.0821 0.81364 1.0807 1.1739 14-Jan-2023 0.25328 -0.25033 -2.0148 0.25242 0.1674 15-Jan-2023 -0.87928 -0.26322 1.5713 0.16888 -0.88458 16-Jan-2023 -0.72874 0.11104 0.61025 2.2831 0.64283
for k = 1:12
Lv = month(T1.date_time) == k;
M = T1(Lv,:);
[~,idx] = maxk(M{:,2},5); % Index Returns 5 Highest Values Of First Variable
Month{k} = M(idx,:);
end
Month{1} % January
ans = 5×6 table
date_time Values1 Values2 Values3 Values4 Values5 ___________ _______ _______ ________ _________ ________ 08-Jan-2023 2.4883 -1.7341 0.48573 0.21777 -1.5177 10-Jan-2023 1.7618 0.17462 0.083165 -1.3276 0.80792 17-Jan-2023 1.4461 0.69264 0.47425 0.53047 -0.08912 03-Jan-2023 1.4347 1.3957 -0.86495 0.38031 -1.3195 12-Jan-2023 1.2937 2.0955 -0.52163 -0.023047 1.8627
Month{12} % December
ans = 5×6 table
date_time Values1 Values2 Values3 Values4 Values5 ___________ _______ ________ ________ ________ ________ 30-Dec-2023 1.3279 1.4798 -0.57554 -1.1291 0.14661 01-Dec-2023 1.0922 0.070399 0.1188 0.46017 -0.16276 18-Dec-2023 1.0347 -0.8301 1.3053 -0.11941 0.96864 21-Dec-2023 1.0141 -1.0614 2.0416 0.016393 -0.35875 24-Dec-2023 0.87875 -1.1881 -0.10361 1.5908 1.2401
Please do not use numbered variables! Simply store the results in an array.
.
  14 Comments
Ancalagon8
Ancalagon8 on 23 Feb 2023
Thank you for your answer, but I meant an empty row (not collumn). Is it possible?
Star Strider
Star Strider on 23 Feb 2023
As always, my pleasure!
The easiest way to find out is to do the experiment, adding:
Month{k} = [Month{k}; []];
That will not throw an error, however it does not affect the result, and neither does:
Month{k} = [Month{k}; cell(1,size(Month{k},2))];
while this works:
Month{k} = [Month{k}; table(NaT,NaN,NaN,NaN, 'VariableNames',Month{k}.Properties.VariableNames)];
however this (and analogues of it) do not:
Month{k} = [Month{k}; table({},[],[],[], 'VariableNames',Month{k}.Properties.VariableNames)];
So it appears not to be possible.
I will leave this up here so you can experiment with it —
date_time = (datetime('01-Jan-2023') : caldays(1) : datetime('31-Dec-2023')).';
Temperature = randn(numel(date_time), 1);
T1 = [table(date_time) array2table(Temperature)]
T1 = 365×2 table
date_time Temperature ___________ ___________ 01-Jan-2023 -1.462 02-Jan-2023 0.29838 03-Jan-2023 -1.2412 04-Jan-2023 0.040549 05-Jan-2023 0.25528 06-Jan-2023 -0.63519 07-Jan-2023 -1.6557 08-Jan-2023 -0.31906 09-Jan-2023 -0.73945 10-Jan-2023 0.34245 11-Jan-2023 0.31167 12-Jan-2023 1.4 13-Jan-2023 0.89639 14-Jan-2023 0.16224 15-Jan-2023 0.22773 16-Jan-2023 -0.16861
VN = T1.Properties.VariableNames;
[Y,M,D] = ymd(T1.date_time);
DN = day(T1.date_time,'dayofyear');
T1 = addvars(T1,M,Y,'AFter','date_time');
T1.Properties.VariableNames = {VN{1},'M','Y',VN{2}}; % Necessary, Since They Show Up As 'Var2' etc. Otherwise
T1
T1 = 365×4 table
date_time M Y Temperature ___________ _ ____ ___________ 01-Jan-2023 1 2023 -1.462 02-Jan-2023 1 2023 0.29838 03-Jan-2023 1 2023 -1.2412 04-Jan-2023 1 2023 0.040549 05-Jan-2023 1 2023 0.25528 06-Jan-2023 1 2023 -0.63519 07-Jan-2023 1 2023 -1.6557 08-Jan-2023 1 2023 -0.31906 09-Jan-2023 1 2023 -0.73945 10-Jan-2023 1 2023 0.34245 11-Jan-2023 1 2023 0.31167 12-Jan-2023 1 2023 1.4 13-Jan-2023 1 2023 0.89639 14-Jan-2023 1 2023 0.16224 15-Jan-2023 1 2023 0.22773 16-Jan-2023 1 2023 -0.16861
for k = 1:12
Lv = month(T1.date_time) == k;
M = T1(Lv,:);
[~,idx] = maxk(M{:,2},5); % Index Returns 5 Highest Values Of First Variable
Month{k} = M(idx,:);
% Q = cell(1,size(Month{k},2))
Month{k} = [Month{k}; table({},[],[],[], 'VariableNames',Month{k}.Properties.VariableNames)];
% Month{k} = [Month{k}; table(NaT,NaN,NaN,NaN, 'VariableNames',Month{k}.Properties.VariableNames)];
end
Month{1} % January
ans = 5×4 table
date_time M Y Temperature ___________ _ ____ ___________ 01-Jan-2023 1 2023 -1.462 02-Jan-2023 1 2023 0.29838 03-Jan-2023 1 2023 -1.2412 04-Jan-2023 1 2023 0.040549 05-Jan-2023 1 2023 0.25528
Month{12} % December
ans = 5×4 table
date_time M Y Temperature ___________ __ ____ ___________ 01-Dec-2023 12 2023 0.23843 02-Dec-2023 12 2023 1.5669 03-Dec-2023 12 2023 -0.48915 04-Dec-2023 12 2023 0.74177 05-Dec-2023 12 2023 -0.47897
.

Sign in to comment.

More Answers (0)

Categories

Find more on Dates and Time in Help Center and File Exchange

Tags

Community Treasure Hunt

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

Start Hunting!