Performance 如何在Matlab中对for循环应用矢量化?

Performance 如何在Matlab中对for循环应用矢量化?,performance,matlab,vectorization,Performance,Matlab,Vectorization,谁能告诉我如何矢量化以下内容: a = randi([6 10],5);; c = unique(a); d = [1:5]; % some comparison Values length should be equal to length(c) Mat = zeros(size(a)); for i = 1:length(c) Mat(a==c(i)) = d(i); end Elapsed time is 0.166673 seconds. %// your method El

谁能告诉我如何矢量化以下内容:

a = randi([6 10],5);; 
c = unique(a);
d = [1:5]; % some comparison Values length should be equal to length(c)

Mat = zeros(size(a));
for i = 1:length(c)
  Mat(a==c(i)) = d(i);
end
Elapsed time is 0.166673 seconds.  %// your method
Elapsed time is 0.006669 seconds.  %// my method
ans =                              %// yes they're equal
    1
结果:

     3     1     5     3     3
     3     5     4     2     3
     5     1     3     3     3
     2     2     2     3     3
     3     5     5     3     4
这里6被1代替,7被2代替,等等


这当然只是一个例子;我真正的
Mat
更像2000×2000。

:这是对原始问题的回答;第二次编辑完全改变了问题,因此下面的答案不再适用。编辑大大简化了问题,因此这个答案仍然是一个很好的起点

基本上,
a
的所有唯一值都将替换为
b
中的相应值。这意味着要分析的矩阵是
b
,唯一的困难在于
b
条件必须适用于
b
中的相应索引

为此,您可以简单地将
a
的所有元素放入
c
定义的组中,并确定
b
中的每个元素属于哪个组。这些信息可用于在
d
中找到适当的索引

换言之:

NewMat = b;
[~, inds] = histc(a(:), c);
NewMat(NewMat(:) > d(inds)) = 0;
一个小型测试,用于比较两种方法的性能并验证其相等性:

a = randi(1000, 74,100);
b = randi(1000, 74,100);

c = unique(a);
d = randi(1000, size(c)); % some comparison Values

%// Your method
tic
NewMat = zeros(size(a));
for i = 1:length(c)
  Mat = zeros(size(a));
  Mat(a==c(i)) = b(a==c(i));
  Mat(Mat > d(i)) =0;
  NewMat = NewMat + Mat;
end
NewMat1 = NewMat;
toc

%// My method
tic
[~,inds] = histc(a(:), c);
b(b(:) > d(inds)) = 0;
NewMat2 = b;
toc

%// validate solution
isequal(NewMat1, NewMat2)
结果:

%// 74 × 100
Elapsed time is 0.151808 seconds.   %// your method 
Elapsed time is 0.001007 seconds.   %// my method
ans =                               %// yes, they're equal
     1
因此,性能提高了约150倍。不是使用74×100而是使用740×1000

%// 740 × 1000
Elapsed time is 27.587543 seconds.  %// your method
Elapsed time is 0.111467 seconds.   %// my method
ans =                               %// yes, they're equal
     1

或相差约250倍的系数。所以很明显,你的方法也比
histc
方法更糟糕。

注意:先阅读我的另一个答案

要在最新编辑中回答问题,请执行以下操作:

[~, inds] = histc(a(:), c);
Mat = reshape(d(inds), size(a));
对600×100数据进行类似测试:

a = randi(500,[600 100]); 
c = unique(a);
d = randi(20, size(c));

tic
Mat = zeros(size(a));
for ii = 1:length(c)
  Mat(a==c(ii)) = d(ii);
end
toc


tic
[~, inds] = histc(a(:), c);
Mat2 = reshape(d(inds), size(a));
toc

isequal(Mat,Mat2)
提供以下信息:

a = randi([6 10],5);; 
c = unique(a);
d = [1:5]; % some comparison Values length should be equal to length(c)

Mat = zeros(size(a));
for i = 1:length(c)
  Mat(a==c(i)) = d(i);
end
Elapsed time is 0.166673 seconds.  %// your method
Elapsed time is 0.006669 seconds.  %// my method
ans =                              %// yes they're equal
    1

速度又相差了大约250倍。

我开始用你问题的旧版本制定答案;新版本实际上看起来简单多了:)啊,好吧,我想这已经足够让你走了。好吧,它确实很简单,我刚刚植入了另一个答案。@user2851655:另请看我的另一个答案,它回答了你目前的问题。@user2851655:不客气;我喜欢这些拼图,所以我真的很高兴:)+1太棒了!我不知道
histc
的第二个输出,它似乎很有用。