在matlab

时间:2015-09-23 13:40:14

标签: matlab

我正在进行一些分析,我正在分析数百个正在进行迭代分析的数据文件。以下是我所拥有的数据类型的示例:

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

请注意,我使用的是一个非常简单的函数作为示例,实际函数更复杂。

这样的两个循环需要很长时间才能运行我的实际数据。是否有更好/更快的方式可以执行上述操作,可能没有循环?

1 个答案:

答案 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倍或更多的加速。