如何在MATLAB中有效地比较两个向量中的元素而不使用循环?

Kri*_*673 3 matlab vectorization

假设我有一个矩阵,A其第一列包含重复项目ID,第二列包含重量.

A= [1   40
    3   33
    2   12
    4   22
    2   10
    3   6
    1   15
    6   29
    4   10
    1   2
    5   18
    5   11
    2   8
    6   25
    1   14
    2   11
    4   28
    3   38
    5   35
    3   9];
Run Code Online (Sandbox Code Playgroud)

我现在想要找出每个实例A及其相关最小权重的差异.为此,我创建了一个矩阵B,其第一列包含第1列中的唯一ID,第2列包含从A第2列中找到的相关最小权重A.

B=[1    2
   2    8
   3    6
   4    10
   5    11
   6    25];
Run Code Online (Sandbox Code Playgroud)

然后,我想在第3列中存储A每个条目的差异及其相关的最小权重.

A= [1   40  38
    3   33  27
    2   12  4
    4   22  12
    2   10  2
    3   6   0
    1   15  13
    6   29  4
    4   10  0
    1   2   0
    5   18  7
    5   11  0
    2   8   0
    6   25  0
    1   14  12
    2   11  3
    4   28  18
    3   38  32
    5   35  24
    3   9   3];
Run Code Online (Sandbox Code Playgroud)

这是我写的代码:

for i=1:size(A,1)
    A(i,3) = A(i,1) - B(B(:,1)==A(i,2),2);
end
Run Code Online (Sandbox Code Playgroud)

但是这段代码需要很长时间才能执行,因为它需要在B每次循环时循环执行A.也就是说,它具有复杂性size(A) x size(B).有没有更好的方法可以在不使用循环的情况下执行此操作,这会更快地执行?

Sue*_*ver 5

您可以使用accumarray首先计算第一列中A每个唯一值的第二列中的最小值A.然后我们可以使用第一列索引到结果,A并与第二列进行比较A以创建第三列.

% Compute the mins
min_per_group = accumarray(A(:,1), A(:,2), [], @min);

% Compute the difference between the second column and the minima
A(:,3) = A(:,2) - min_per_group(A(:,1));
Run Code Online (Sandbox Code Playgroud)