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 个评论

How do you want to store your final output?
All values in a numeric array (12x5 or 5x12 )? If otherwise, please specify.

(Answers Dev) Restored edit

 采纳的回答

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.
.
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 的更多信息

标签

Community Treasure Hunt

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

Start Hunting!

Translated by