问题
在 MATLAB 中,我有 2 个具有整数值的相同大小的一维数组。考虑到同一索引处的值是一对,我想计算每对有多少对并将其存储在矩阵中以便稍后将其打印为热图。
这是我要存档的一个小例子:
v1 = [1, 0, 1, 0, 1];
v2 = [1, 1, 0, 1, 1];
% Magic happens here
heatMatrix = [0, 2;
1, 2];
结果如下,因为我们有:
- 0 时间对 v1=0, v2=0 (heatMatrix[1, 1])
- 2 次对 v1=0, v2=1(索引 2 和 4,heatMatrix[1, 2])
- 1 次对 v1=1,v2=0(索引 3,heatMatrix[2, 1])
- 2 次对 v1=1,v2=1(索引 1 和 5,heatMatrix[2, 2])
我的代码
我已经使用 MATLAB 循环做到了这一点,这比合理的速度慢,尤其是对于长向量:
% Alocating random vectors
rng(0);
maxVal = 255;
nbElem = 1e6;
v1 = randi(nbElem, 1);
v2 = randi(nbElem, 1);
heatMatrix = zeros(maxVal, maxVal);
% Creating heat matrix
tic();
for ii = 1:maxVal
for jj = 1:maxVal
heatMatrix(ii, jj) = sum((v1 == i) & (v2 == j));
end
end
toc();
性能问题
我必须在 1e7 个元素的范围内处理长向量。我正在使用 Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz 和 7.5 GB RAM。我的表演如下:
问题
我正在寻找一种方法来加快此任务的执行速度。我主要是在寻找一种以更智能的方式来引导或执行任务的方法(也许有一个我不知道的 MATLAB 函数)。
最佳答案
选项 1:accumarray()
accumarray()
可以处理二维索引,所以:
v1 = [1, 0, 1, 0, 1];
v2 = [1, 1, 0, 1, 1];
hm = accumarray([v1;v2].'+1,1)
% hm = [0, 2;
% 1, 2];
只需确保您的索引以 1 开头即可。
选项 2:sparse()
sparse()
可以处理重复索引,所以:
v1 = [1, 0, 1, 0, 1];
v2 = [1, 1, 0, 1, 1];
hm = full(sparse(v1+1,v2+1,1))
% hm = [0, 2;
% 1, 2];
这两个选项都比您的解决方案快得多,也比@BillBokeey 的解决方案快。但看起来 accumarray 更快一些。
关于performance - 如何有效地创建两个向量中所有值对的热图?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72701308/