我正在进行一些分析,我正在分析数百个正在进行迭代分析的数据文件。以下是我所拥有的数据类型的示例:
start_time = datenum('1990-01-01');
end_time = datenum('2009-12-31');
time = start_time:end_time;
datx = rand(length(time),1);
daty = datx-2;
我有一个时间变量和两个数据变量。
加载数据后,我需要通过函数传递数据。但是,我需要首先包括第1年的数据,然后是第1年到第2年的数据。 1到3,1到4,依此类推,直到我通过整个系列的函数传递数据。这可以通过以下循环执行:
% split into different years
datev = datevec(time);
iyear = datev(:,1);
unique_year = unique(iyear);
for k = 1:length(unique_year);
idx = find(iyear >= unique_year(1) & iyear <= unique_year(k));
% select data for year
d_time = time(idx);
d_datx = datx(idx);
d_daty = daty(idx);
% now select individual years from this subset
datev2 = datevec(d_time);
iyear2 = datev2(:,1);
unique_year2 = unique(iyear2);
for k2 = 1:length(unique_year2);
idx2 = find(iyear2 == unique_year2(k2));
% select data for year
d_time2 = d_time(idx2);
d_datx2 = d_datx(idx2);
d_daty2 = d_daty(idx2);
% pass through some function
mae_out = some_function(d_datx2, d_daty2);
mae(k2) = mae_out;
end
mean_mae(k) = mean(mae);
end
function mae = some_function(datx, daty)
mae = mean(abs(datx - daty));
end
请注意,我使用的是一个非常简单的函数作为示例,实际函数更复杂。
这样的两个循环需要很长时间才能运行我的实际数据。是否有更好/更快的方式可以执行上述操作,可能没有循环?
答案 0 :(得分:0)
如果记录上一个结果,则不需要内循环。您目前正在计算(20+21)/2 = 210
次迭代,但您只需要计算20
。这里的关键是mean(a(1:k)) == (mean(a(1:k-1))*(k-1) + a(k)) / k
(通过均值的定义)。另一个优化是使用逻辑索引而不是find。它占用了更多的空间,但速度更快。
% split into different years
datev = datevec(time);
iyear = datev(:,1);
unique_year = unique(iyear);
for k = 1:length(unique_year);
idx = (iyear == unique_year(k));
% select data for year
d_time = time(idx);
d_datx = datx(idx);
d_daty = daty(idx);
mae_out = some_function(d_datx, d_daty);
if k == 1
mean_mae(k) = mean_out;
else
mean_mae(k) = (mean_mae(k-1) * (k-1) + mean(mean_out)) / k;
end
end
function mae = some_function(datx, daty)
mae = mean(abs(datx - daty));
end
正如您所看到的,这应该会给您大约20倍或更多的加速。