假设我的矩阵A是比较函数的输出,即只有值0和1的逻辑矩阵。对于大小为 3*4 的小矩阵,我们可能会有这样的内容:
A =
1 1 0 0
0 0 1 0
0 0 1 1
现在,我正在生成另一个与 A 大小相同的矩阵 B,但它的行填充了 A 的索引,并且每行中的任何剩余值都设置为零。
B =
1 2 0 0
3 0 0 0
3 4 0 0
目前,我在 A 的每一行上使用 find 函数来获取矩阵 B.完整的代码可以编写为:
A=[1,1,0,0;0,0,1,0;0,0,1,1];
[rows,columns]=size(A);
B=zeros(rows,columns);
for i=1:rows
currRow=find(A(i,:));
B(i,1:length(currRow))=currRow;
end
对于大型 martix,根据 Matlab Profiler 计算"查找"功能需要时间。有没有办法更快地生成矩阵 B?
注意: 矩阵 A 每行的列数超过 1000 列,但非零元素永远不会超过 50 列。在这里,我将矩阵 B 与 A 的大小相同,但矩阵 B 的列大小可以小得多。
我建议使用parfor
,但这里的开销太大了,而且它有更多的问题,所以这不是一个好的解决方案。
rows = 5e5;
cols = 1000;
A = rand(rows, cols) < 0.050;
I = uint16(1:cols);
B = zeros(size(A), 'uint16');
% [r,c] = find(A);
tic
for i=1:rows
% currRow = find(A(i,:));
currRow = I(A(i,:));
B(i,1:length(currRow)) = currRow;
end
toc
@Cris建议将find
替换为索引操作。它将性能提高了约 10%。
显然,没有更好的优化,除非B
需要以您告诉的特定形式。如果不需要矩阵形式的索引,我建议使用[r,c] = find(A);
。