Improve part of code using a loop

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

Dyuman Joshi
Dyuman Joshi 2023년 2월 4일
편집: Dyuman Joshi 2023년 2월 4일
How do you want to store your final output?
All values in a numeric array (12x5 or 5x12 )? If otherwise, please specify.
Rena Berman
Rena Berman 2025년 1월 13일

(Answers Dev) Restored edit

 채택된 답변

Star Strider
Star Strider 2023년 2월 4일

0 개 추천

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.
.

댓글 수: 7

As always, my pleasure!
It is being stored in a variable (cell array) that I call ‘Month’ that has 12 elements, one for each month. This is much easier to work with than numbered variables. Just address them as I do here to get the values for each month —
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.829 02-Jan-2023 0.87981 03-Jan-2023 1.8844 04-Jan-2023 -1.5862 05-Jan-2023 -0.98092 06-Jan-2023 0.18252 07-Jan-2023 -0.19155 08-Jan-2023 -0.054607 09-Jan-2023 -0.25883 10-Jan-2023 0.08625 11-Jan-2023 0.40258 12-Jan-2023 1.6588 13-Jan-2023 -0.80509 14-Jan-2023 0.024423 15-Jan-2023 -0.0064415 16-Jan-2023 -0.39512
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×2 table
date_time Temperature ___________ ___________ 03-Jan-2023 1.8844 12-Jan-2023 1.6588 21-Jan-2023 1.3651 02-Jan-2023 0.87981 30-Jan-2023 0.81799
Month{12} % December
ans = 5×2 table
date_time Temperature ___________ ___________ 16-Dec-2023 2.4482 11-Dec-2023 1.9463 08-Dec-2023 1.9352 15-Dec-2023 1.8556 03-Dec-2023 1.5551
The addressing will be slightly different for a timetable, since there would be only one variable in a timetable version of ‘T1’.
The maxk call would then be:
[~,idx] = maxk(M{:,2},1); % Index Returns 5 Highest Values Of First Variable
The rest of the code is unchanged.
.
Star Strider
Star Strider 2023년 2월 5일
As always, my pleasure!
Yes.
Try something like this —
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 0.88442 02-Jan-2023 0.88671 03-Jan-2023 -0.69933 04-Jan-2023 -0.034487 05-Jan-2023 0.65367 06-Jan-2023 0.18407 07-Jan-2023 -1.5565 08-Jan-2023 -0.18332 09-Jan-2023 0.2518 10-Jan-2023 -0.19332 11-Jan-2023 0.046373 12-Jan-2023 -0.51374 13-Jan-2023 -0.50209 14-Jan-2023 -0.8595 15-Jan-2023 -0.83822 16-Jan-2023 -0.33427
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,:);
VN = Month{k}.Properties.VariableNames;
[Y,M,D] = ymd(Month{k}.date_time);
Month{k} = addvars(Month{k},D,M,Y,'AFter','date_time');
Month{k}.Properties.VariableNames = {VN{1},'D','M','Y',VN{2}}; % Necessary, Since They Show Up As 'Var2' etc. Otherwise
end
Month{1} % January
ans = 5×5 table
date_time D M Y Temperature ___________ __ _ ____ ___________ 21-Jan-2023 21 1 2023 2.1431 17-Jan-2023 17 1 2023 1.8234 25-Jan-2023 25 1 2023 1.171 29-Jan-2023 29 1 2023 1.045 19-Jan-2023 19 1 2023 0.97233
Month{12} % December
ans = 5×5 table
date_time D M Y Temperature ___________ __ __ ____ ___________ 13-Dec-2023 13 12 2023 2.1362 12-Dec-2023 12 12 2023 1.764 01-Dec-2023 1 12 2023 1.4348 29-Dec-2023 29 12 2023 1.401 15-Dec-2023 15 12 2023 1.1454
I chose to keep the ‘date_time’ variable here (and I do not recommend removing it), since it could have time information that may become necessary in other applications. If you want to remove the 'date_time' variable, use the removevars function.
.
As always, my pleasure!
Yes!
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 0.4125 02-Jan-2023 -1.8553 03-Jan-2023 1.3607 04-Jan-2023 3.0349 05-Jan-2023 -0.99181 06-Jan-2023 -1.3366 07-Jan-2023 -1.2793 08-Jan-2023 -0.41486 09-Jan-2023 -0.52116 10-Jan-2023 0.54241 11-Jan-2023 -0.36556 12-Jan-2023 0.87537 13-Jan-2023 0.0006959 14-Jan-2023 1.6565 15-Jan-2023 0.7976 16-Jan-2023 -0.022317
VN = T1.Properties.VariableNames;
[Y,M,D] = ymd(T1.date_time);
DN = day(T1.date_time,'dayofyear');
T1 = addvars(T1,D,M,Y,DN,'AFter','date_time');
T1.Properties.VariableNames = {VN{1},'D','M','Y','Day Number',VN{2}}; % Necessary, Since They Show Up As 'Var2' etc. Otherwise
T1
T1 = 365×6 table
date_time D M Y Day Number Temperature ___________ __ _ ____ __________ ___________ 01-Jan-2023 1 1 2023 1 0.4125 02-Jan-2023 2 1 2023 2 -1.8553 03-Jan-2023 3 1 2023 3 1.3607 04-Jan-2023 4 1 2023 4 3.0349 05-Jan-2023 5 1 2023 5 -0.99181 06-Jan-2023 6 1 2023 6 -1.3366 07-Jan-2023 7 1 2023 7 -1.2793 08-Jan-2023 8 1 2023 8 -0.41486 09-Jan-2023 9 1 2023 9 -0.52116 10-Jan-2023 10 1 2023 10 0.54241 11-Jan-2023 11 1 2023 11 -0.36556 12-Jan-2023 12 1 2023 12 0.87537 13-Jan-2023 13 1 2023 13 0.0006959 14-Jan-2023 14 1 2023 14 1.6565 15-Jan-2023 15 1 2023 15 0.7976 16-Jan-2023 16 1 2023 16 -0.022317
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 D M Y Day Number Temperature ___________ __ _ ____ __________ ___________ 31-Jan-2023 31 1 2023 31 -0.061538 30-Jan-2023 30 1 2023 30 -1.5446 29-Jan-2023 29 1 2023 29 -0.73438 28-Jan-2023 28 1 2023 28 0.054624 27-Jan-2023 27 1 2023 27 -0.33551
Month{12} % December
ans = 5×6 table
date_time D M Y Day Number Temperature ___________ __ __ ____ __________ ___________ 31-Dec-2023 31 12 2023 365 0.50683 30-Dec-2023 30 12 2023 364 -1.0811 29-Dec-2023 29 12 2023 363 -0.30576 28-Dec-2023 28 12 2023 362 0.59184 27-Dec-2023 27 12 2023 361 -2.0968
.
As always, my pleasure!
Just add only those variables —
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 -0.8472 02-Jan-2023 -0.39597 03-Jan-2023 0.96971 04-Jan-2023 1.1996 05-Jan-2023 1.3655 06-Jan-2023 -0.31902 07-Jan-2023 1.0043 08-Jan-2023 -0.35093 09-Jan-2023 1.4086 10-Jan-2023 1.2748 11-Jan-2023 -1.6748 12-Jan-2023 -0.2835 13-Jan-2023 0.086737 14-Jan-2023 -0.787 15-Jan-2023 1.2044 16-Jan-2023 -0.082712
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 -0.8472 02-Jan-2023 1 2023 -0.39597 03-Jan-2023 1 2023 0.96971 04-Jan-2023 1 2023 1.1996 05-Jan-2023 1 2023 1.3655 06-Jan-2023 1 2023 -0.31902 07-Jan-2023 1 2023 1.0043 08-Jan-2023 1 2023 -0.35093 09-Jan-2023 1 2023 1.4086 10-Jan-2023 1 2023 1.2748 11-Jan-2023 1 2023 -1.6748 12-Jan-2023 1 2023 -0.2835 13-Jan-2023 1 2023 0.086737 14-Jan-2023 1 2023 -0.787 15-Jan-2023 1 2023 1.2044 16-Jan-2023 1 2023 -0.082712
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×4 table
date_time M Y Temperature ___________ _ ____ ___________ 01-Jan-2023 1 2023 -0.8472 02-Jan-2023 1 2023 -0.39597 03-Jan-2023 1 2023 0.96971 04-Jan-2023 1 2023 1.1996 05-Jan-2023 1 2023 1.3655
Month{12} % December
ans = 5×4 table
date_time M Y Temperature ___________ __ ____ ___________ 01-Dec-2023 12 2023 0.21611 02-Dec-2023 12 2023 0.084954 03-Dec-2023 12 2023 -0.70966 04-Dec-2023 12 2023 -1.1687 05-Dec-2023 12 2023 1.2007
.
I assume you mean and empty column.
Probably the easiest way would be to create an empty table and concatenate 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 -0.88708 02-Jan-2023 0.52889 03-Jan-2023 2.2822 04-Jan-2023 -0.20247 05-Jan-2023 -1.7595 06-Jan-2023 -0.44609 07-Jan-2023 1.1342 08-Jan-2023 -0.17281 09-Jan-2023 0.12262 10-Jan-2023 -0.10406 11-Jan-2023 -0.57959 12-Jan-2023 -0.93386 13-Jan-2023 -0.24131 14-Jan-2023 -0.63014 15-Jan-2023 -0.56083 16-Jan-2023 -0.47346
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 -0.88708 02-Jan-2023 1 2023 0.52889 03-Jan-2023 1 2023 2.2822 04-Jan-2023 1 2023 -0.20247 05-Jan-2023 1 2023 -1.7595 06-Jan-2023 1 2023 -0.44609 07-Jan-2023 1 2023 1.1342 08-Jan-2023 1 2023 -0.17281 09-Jan-2023 1 2023 0.12262 10-Jan-2023 1 2023 -0.10406 11-Jan-2023 1 2023 -0.57959 12-Jan-2023 1 2023 -0.93386 13-Jan-2023 1 2023 -0.24131 14-Jan-2023 1 2023 -0.63014 15-Jan-2023 1 2023 -0.56083 16-Jan-2023 1 2023 -0.47346
NewVariable = table('Size',[size(T1,1),1], 'VariableTypes',{'double'}, 'VariableNames',{'NewVariable'});
T1 = [T1 NewVariable]
T1 = 365×5 table
date_time M Y Temperature NewVariable ___________ _ ____ ___________ ___________ 01-Jan-2023 1 2023 -0.88708 0 02-Jan-2023 1 2023 0.52889 0 03-Jan-2023 1 2023 2.2822 0 04-Jan-2023 1 2023 -0.20247 0 05-Jan-2023 1 2023 -1.7595 0 06-Jan-2023 1 2023 -0.44609 0 07-Jan-2023 1 2023 1.1342 0 08-Jan-2023 1 2023 -0.17281 0 09-Jan-2023 1 2023 0.12262 0 10-Jan-2023 1 2023 -0.10406 0 11-Jan-2023 1 2023 -0.57959 0 12-Jan-2023 1 2023 -0.93386 0 13-Jan-2023 1 2023 -0.24131 0 14-Jan-2023 1 2023 -0.63014 0 15-Jan-2023 1 2023 -0.56083 0 16-Jan-2023 1 2023 -0.47346 0
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×5 table
date_time M Y Temperature NewVariable ___________ _ ____ ___________ ___________ 01-Jan-2023 1 2023 -0.88708 0 02-Jan-2023 1 2023 0.52889 0 03-Jan-2023 1 2023 2.2822 0 04-Jan-2023 1 2023 -0.20247 0 05-Jan-2023 1 2023 -1.7595 0
Month{12} % December
ans = 5×5 table
date_time M Y Temperature NewVariable ___________ __ ____ ___________ ___________ 01-Dec-2023 12 2023 -0.58861 0 02-Dec-2023 12 2023 -0.78759 0 03-Dec-2023 12 2023 0.48172 0 04-Dec-2023 12 2023 -0.23827 0 05-Dec-2023 12 2023 -0.98037 0
.
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
.

추가 답변 (0개)

This question is locked.

카테고리

도움말 센터File Exchange에서 Dates and Time에 대해 자세히 알아보기

태그

질문:

2023년 2월 4일

Locked:

2025년 1월 13일

Community Treasure Hunt

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

Start Hunting!

Translated by