查找Matlab中的每一行是否重复

时间:2017-03-23 15:33:51

标签: matlab

我在维度A的Matlab中有一个矩阵MXN。我想创建一个维B的向量Mx1,其中B(i)=1如果A(i,:)从未在A多次重复,0则为A=[1 2 3; 4 5 6; 1 2 3; 7 8 9]; B=[0;1;0;1];

例如

[vu,vx,vx]=unique(A,'rows');
n=accumarray(vx,1);
C=[vu n]

此代码

C

有助于查找每行的出现次数。因此,通过添加一个循环,我应该能够B根据需要获得M。但是,在我的实际情况中,project.json非常大(80000)。我能用得更快吗?

1 个答案:

答案 0 :(得分:10)

您的代码的问题是unique的第二个输出仅返回每个唯一值的第一次出现,第三个输出将索引数组返回到对应的第一个输出中对输入。这些都不能直接得到你想要的东西。如果你把它们组合起来,就可以得到你想要的东西

[~, a, b] = unique(A, 'rows');
B = accumarray(a(b), 1, [size(A, 1), 1]) == 1;

另一种方法是使用ismember的第二个输出和'rows'选项来查找共享行的索引。然后,您可以使用accumarray确定重复行的次数,并将结果与​​1进行比较

[~, bi] = ismember(A, A, 'rows');
B = accumarray(bi, 1, [size(A, 1), 1]) == 1;

在简单的基准测试中,使用unique的选项往往会产生最佳结果

function comparison()

    nRows = round(linspace(100, 100000, 30));

    times1 = nan(size(nRows));
    times2 = nan(size(nRows));

    for k = 1:numel(nRows)
        A = randi(10, nRows(k), 4);
        times1(k) = timeit(@()option1(A));
        times2(k) = timeit(@()option2(A));
    end

    figure
    p(1) = plot(nRows, times1 * 1000, 'DisplayName', 'unique');
    hold on
    p(2) = plot(nRows, times2 * 1000, 'DisplayName', 'ismember');
    ylabel('Execution time (ms)')
    xlabel('Rows in A')
    legend(p)
end


function B = option1(A)
    [~, a, b] = unique(A, 'rows');
    B = accumarray(a(b), 1, [size(A, 1), 1]) == 1;
end

function B = option2(A)
    [~, bi] = ismember(A, A, 'rows');
    B = accumarray(bi, 1, [size(A, 1), 1]) == 1;
end

enter image description here