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
的第二个输出,它似乎很有用。