【问题标题】:Vectorization instead of nested for loops in matlab向量化而不是matlab中的嵌套for循环
【发布时间】:2017-01-16 09:48:10
【问题描述】:

我无法在 matlab 中对这个 for 循环进行矢量化,这真的很慢。 tvec 和 data 分别是 N×6 和 N×4 数组,它们是函数的输入。

% preallocate
sVec = size(tvec) 
tvec_ab = zeros(sVec(1),6);
data_ab = zeros(sVec(1),4);
inc = 0;
for i = 1:12
    for j = 1:31
       inc = inc +1;
       [I,~] = find(tvec(:,3)==i & tvec(:,2)== j,1,'first');
       if(I > 0)
           tvec_ab(inc,:) = tvec(I,:);
           data_ab(inc,:) = sum(data( (tvec(:,3) == j) & (tvec(:,2)==i) ,:));
       end
    end
end

% set output values
tvec_a = tvec_ab(1:inc,:);
data_a = data_ab(1:inc,:);

tvec 中的每一行代表数据矩阵中同一行中数据的时间戳。下面你可以看到一行的样子:

tvec: [year, month, day, hour, minute, second]

data: [dataA, dataB, dataC, dataD]

在主程序中,我们可以选择在月、日或小时之后“聚合”。 上面的代码是选项'DAY' 的聚合如何发生的示例。

当天的第一个时间戳是我们希望输出 tvec_a 在当天的行中包含的时间戳。

当天的数据输出(在本例中为行)将是当天所有数据的总和。示例:

data:

[data1ADay1, data1BDay1, data1CDay1, data1DDay1;
 data2ADay1, data2BDay1, data2CDay1, data2DDay1]

汇总数据:

[data1ADay1 + data2ADay1, data1BDay1 + data2BDay1, data1CDay1+ data2CDay1, 
data1DDay1+data2DDay1]

【问题讨论】:

  • 好像N == 12*31
  • 是的,在此示例的结果矩阵中,N 将是您描述的结果。但是我们不知道输入向量中的 N 有多大,也不知道用户选择了哪个聚合选项(在这种情况下它是天的聚合,因此是 12*31),但是如果用户例如选择小时它将是 N == 12*31*24
  • 听起来像accumarray 是去这里的方式
  • 为什么在某处写tvec(:,3) == j而在某处写tvec(:,3)==i

标签: matlab vectorization


【解决方案1】:

矢量化版本(未完全测试)

[x y] = meshgrid(1:12,1:31);
XY=[x(:) Y(:)];
[I,loc]=ismember(XY,tvec(:,2:3),'rows');
tvec_ab(I)=tvec(loc(loc>0),:);
acm = accumarray(tvec(:,2:3),data);
data_ab(I) = acm(sub2ind(size(acm),tvec(:,2),tvec(:,3)));

【讨论】:

    【解决方案2】:

    实际上我自己找到了一种方法:

     %J is the indexes of the first unique days ( eg. if there is multiple
        %data from january 1., the first time stamp from january 1. will be
        %the time samp for our output)
        [~,J,K] = unique(tvec(:,2:3),'rows');
        %preallocate
        tvec_ab = zeros(length(J),6);
        data_ab = zeros(length(J),4);   
        tvec_ab = tvec(J,:);
        %sum all data from the same days together column wise.
        for i = 1:4
            data_ab(:,i) = accumarray(K,data(:,i));
        end
        %set output
        data_a = data_ab;
        tvec_a = tvec_ab;
    

    感谢您的回复

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-06
      • 1970-01-01
      • 1970-01-01
      • 2011-09-16
      • 1970-01-01
      • 1970-01-01
      • 2013-03-03
      • 2021-07-29
      相关资源
      最近更新 更多