Je suis sûr que vous pouvez vectoriser cela pour travailler plus vite, mais cela devrait faire l'affaire. Je n'ai pas testé correctement
% range of years
years = 2000:2016;
leap_years = [2000 2004 2008 2012 2016];
% Generating random data
nr_of_years = numel(years);
rainfall_data = cell(nr_of_years, 1);
for i=1:nr_of_years
nr_of_days = 365;
if ismember(years(i), leap_years);
nr_of_days = 366;
end
rainfall_data{i} = rand(180, 360, nr_of_days);
end
Le code réel que vous avez besoin est ci-dessous
% fixed stuff
months = 12;
nr_of_days = [31 28 31 30 31 30 31 31 30 31 30 31];
nr_of_days_leap = [31 29 31 30 31 30 31 31 30 31 30 31];
% building vectors of month indices for days
month_indices = [];
month_indices_leap = [];
for i=1:months
month_indices_temp = repmat(i, nr_of_days(i), 1);
month_indices_leap_temp = repmat(i, nr_of_days_leap(i), 1);
month_indices = [month_indices; month_indices_temp];
month_indices_leap = [month_indices_leap; month_indices_leap_temp];
end
% the result will be stored here
result = zeros(size(rainfall_data{i}, 1), size(rainfall_data{i}, 2), months*nr_of_years);
for i=1:nr_of_years
% determining which indices to use depending if it is a leap year
month_indices_temp = month_indices;
if size(rainfall_data{i}, 3)==366
month_indices_temp = month_indices_leap;
end
% data for the current year
current_data = rainfall_data{i};
% this holds the data for current year
monthy_sums = zeros(size(rainfall_data{i}, 1), size(rainfall_data{i}, 2), months);
for j=1:months
monthy_sums(:,:,j) = sum(current_data(:,:,j==month_indices_temp), 3);
end
% putting it into the combined matrix
result(:,:,((i-1)*months+1):(i*months)) = monthy_sums;
end
Vous pouvez probablement obtenir une solution plus élégante à l'aide à construire datetime
, datestr
et datenum
, mais je ne suis pas sûr que ceux ne être beaucoup plus rapide ou plus court.
EDIT: Une alternative utilisant des fonctions intégrées de date
months = 12;
% where the result will be stored
result = zeros(size(rainfall_data{i}, 1), size(rainfall_data{i}, 2), months*nr_of_years);
for i=1:nr_of_years
current_data = rainfall_data{i};
% first day of the year
year_start_timestamp = datenum(datetime(years(i), 1, 1));
% holding current sums
monthy_sums = zeros(size(current_data, 1), size(current_data, 2), months);
% finding the month indices vector
datetime_obj = datetime(datestr(year_start_timestamp:(year_start_timestamp+size(current_data, 3)-1)));
month_indices = datetime_obj.Month;
% summing
for j=1:months
monthy_sums(:,:,j) = sum(current_data(:,:,j==month_indices), 3);
end
% result
result(:,:,((i-1)*months+1):(i*months)) = monthy_sums;
end
Cette 2ème solution a pris 1,45 secondes pour moi, par rapport à 1,2 secondes pour la première solution. Les résultats étaient les mêmes pour les deux cas. J'espère que cela t'aides.
Le plus gros problème avec ceci est la non-uniformité des mois (ils ont différents nombre de jours) –
Oui, pendant la période 2004 et 2008 sont des années bissextiles. – SONY