假设我有两个矩阵:
A = [1;
2;
3;
4;
5]
和
B = [1 1 2 1;
2 3 3 4;
5 5 5 5;
1 4 4 4;
5 5 1 2]
我需要一个结果矩阵来显示 A 中的项目在 B 中的相应行中出现了多少次,如下所示:
C = [3;
1;
0;
3;
2]
目前,我正在使用 for 循环内的 ismember 来执行此操作,并将每行的结果相加。但由于矩阵的大小,这需要很长时间。有没有不使用循环就可以做到这一点?
编辑以显示我当前的代码:
for i=1:1:length(A)
C(i) = sum(ismember(B(i,:),A(i)),2);
end
但实际上,我的矩阵有超过 500k 行,我希望通过删除循环来提高该代码的效率。
简短答案
您只需使用,它将使用隐式扩展将的每个元素与的整行
==
进行比较,并输出匹配的逻辑数组,然后对每行求和以计算匹配数A
B
根据和的生成方式
A
,B
避免对浮点数进行直接相等比较通常是一个好主意(参见此处),因此确保A
和B
在某个较小的容差范围内可能会更为稳健,即这里的减法将使用与
==
第一个示例相同的隐式扩展来A
跨列传播B
。基准测试
出于兴趣,我对四种情况进行了基准测试
C
因此它会随着循环而增长。C
为正确大小的数组NaN
,这通常是加快循环速度的好方法。与 (1) 相比,速度提高了约 18%。==
而不是ismember
,因为你正在比较整数,所以我期望==
它比 更快ismember
。与 (1) 相比,速度提高了 ~62%。==
或abs(..)<tol
方法都同样快,所以我只展示了后者。与 (1) 相比,速度提高了约 94%。测试用例的结果为
length(A) = 1e6
和 100 列B
:根据输入矩阵的大小、预期的匹配数等,这些时间节省的里程可能会有所不同。下面的完整代码可供您测试其他情况。
代码: