我相信你可以通過矢量化來更快地工作,但它應該完成這項工作。沒有正確測試
% 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
你需要的實際代碼如下
% 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
可以使用建立datetime
,datestr
和datenum
可能實現更完美的解決方案,但我不知道那些會要快很多或更短。
編輯:另一種使用內置的日期函數
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
這第二個解決了1.45秒對我來說,相比於1.2秒,第一個解決方案。兩種情況的結果都是一樣的。希望這可以幫助。
這個最大的問題是個月的非均勻性(它們具有不同的量天) –
是,在時間段2004年和2008年是閏年。 – SONY