【问题标题】:How to execute for more faster in Matlab如何在 Matlab 中更快地执行
【发布时间】:2018-12-07 06:44:35
【问题描述】:

我必须执行这个循环:

load('Y');
X_test = ...;
Y_test = ...;
X_train = ...;
Y_train = ...;

    for i=1:length(Y.Y)
        if Y.Y(i,1) == l
            current_test_data = [current_test_data; X_test(i,:)];
            current_test_labes = [current_test_labes; Y_test(i,:)];
        else
            current_train_data = [current_train_data; X_train(i,:)];
            current_train_labes = [current_train_labes; Y_train(i,:)];            
        end
    end

但是 length(Y.Y) 是 2300250 所以这个执行需要很长时间。有更快的方法吗?

【问题讨论】:

  • 您附加错误。如果您需要追加,请执行x(end+1)=0,而不是x=[x,0]。见here。但更好的是预先分配。您可以通过创建一个足够大的数组来容纳尽可能大的输出,然后在循环结束时对其进行修剪,从而获得巨大的收益。像你在这里做的那样在循环中递增数组是非常昂贵的。
  • 预分配例如我的代码中的什么?你指的是“current_test_data”之类的?
  • 是的,创建一个足够大的数组来保存您要保存的数据,因此您不需要将数据附加到数组中。见:mathworks.com/help/matlab/matlab_prog/preallocating-arrays.html
  • 是的。试试看。
  • 这里不能只使用逻辑索引吗?摆脱循环并使用idx = (Y.Y(:,1) == l); current_test_data = X_test(idx, :); current_test_labes = Y_test(idx,:); 等?如果这不起作用,请提供minimal reproducible example,我们可以对其进行测试。

标签: matlab performance for-loop


【解决方案1】:

从性能上来说,你做的确实不是很好。

第一个问题是循环。 Matlab 处理它们的速度不是很快;在可能的情况下,应该首选矢量化操作,因为它们已经得到了很好的优化。例如,执行A=B.*C 比执行for ii=1:length(B), A(ii)=B(ii)*C(ii);end 快得多

第二个问题是您在循环中连接数组。 current_test_data 开始是一个随着时间增长的小数组。每次添加一些数据时,都需要重新分配内存。数据可能必须移动到内存中的另一个位置。由于 Matlab 以列主要顺序存储数据,因此添加额外的行也意味着必须移动除第一列之外的所有样本(而添加额外的列只是在末尾附加数据)。所有这一切共同造成了糟糕的表现。对于小型阵列,这可能不明显;但是当你开始在每次迭代时在内存中移动兆字节或更多的数据时,性能会直线下降

当数组的最终大小已知时,通常的解决方案是预先分配数组,例如current_test_data = zeros(expected_rows,expected_columns);,然后将数据直接放在它所属的位置:current_test_data(jj,:) = some_matrix(ii,:);。没有更多的内存分配,没有更多的内存移动,没有更多的洗牌样本。

但是,在您的具体情况下,解决方案在于第一点:使用矢量化表示法是解决方案。它会将数组预先分配到正确的大小并有效地复制数据。

sel = Y.Y(:,1)==1; % Builds a logical vector
% Selects data based on logical vector
current_test_data =  X_test(sel,:);
current_test_labes = Y_test(sel,:);
current_train_data = X_train(~sel,:);
current_train_labes = Y_train(~sel,:);  

【讨论】:

  • 在这种情况下如何连接结果?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-20
  • 2013-10-08
  • 2015-03-19
  • 1970-01-01
  • 2010-10-13
  • 2013-04-29
相关资源
最近更新 更多