首页 > 解决方案 > 如何比较和添加数组的元素

问题描述

我想取一个数组让我们说 3x5 如下

1 3 5
1 3 5
2 8 6
4 5 7
4 5 8

并编写一个代码来创建一个新数组,如果第一列和第二列中的数字等于其下一行中的数字,则该数组将第三列与前一个数字相加。

由于第 1 行和第 2 行中的前两个值,则将第 1 行和第 2 行中的第三个元素相加

所以上面数组的输出应该是这样的

1 3 10
2 8 6
4 5 15

标签: arraysmatlabequality

解决方案


该函数accumarray(subs,val)使用下标 subs 来累积向量 val 的元素。所以我们可以使用这个函数对第一列和第二列中具有相同值的第三列中的元素求和。我们可以用unique(...,'rows')它来确定哪些值对是唯一的。

%Example data
A = [1 3 5,
     1 3 5,
     2 3 6,
     4 5 7,
     4 5 7]

%Get the unique pair of value based on the first two column (uni) and the associated index.
[uni,~,sub] = unique(A(:,1:2),'rows');

%Create the result using accumarray.
R = [uni, accumarray(sub,A(:,3))]

如果订单很重要,那么脚本会稍微复杂一点:

%Get the unique pair of value based on the first two column (uni) and the associated index.
[uni,~,sub] = unique(A(:,1:2),'rows');

%Locate the consecutive similar row with this small tricks
dsub = diff([0;sub])~=0;

%Create the adjusted index
subo = cumsum(dsub);

%Create the new array
R = [uni(sub(dsub),:), accumarray(subo,A(:,3))]

或者您可以使用 for 循环获得相同的结果:

R = A(1,:)
for ii = 2:length(A)
    if all(A(ii-1,1:2)==A(ii,1:2))
        R(end,3) = R(end,3)+A(ii,3)
    else
        R(end+1,:) = A(ii,:)
    end
end

基准:

100000x3在 mathworks 实时编辑器上有一个大小为 A 的数组:

for 循环大约需要5.5s(没有预分配,所以它很慢)

矢量化方法大约需要0.012s


推荐阅读