如何在矩阵的每一行中找到唯一元素的数量?

时间:2016-05-01 19:03:59

标签: matlab matrix unique

我正在尝试实现某种插值算法。 I是一个N * 4矩阵,保留N个其他点的周围点的索引。但是I的每一行中的元素可能不是唯一的,这意味着它们中的两个或更多个可以指代单个点。我想知道每行中有多少个唯一索引,我想尽快做到N很大!

3 个答案:

答案 0 :(得分:2)

您需要在每一行使用unique函数并计算结果的元素:

arrayfun(@(x) numel(unique(I(x,:))), (1:size(I,1)).')

转换索引数组,使结果为列向量。

答案 1 :(得分:1)

嗯,Mohsen's answer是此问题的一般解决方案,但arrayfun对我来说太慢了。所以我想了一下它,发现了一个更快的解决方案。 我比较所有列对,如果它们相等则增加一个计数器:

tic;
S = zeros(N, 1, 'uint32');
Nu = S+4; % in my case most of point are surrounded by four different points
for i=1:3
    for j=(i+1):4
        S = S + uint32(I(:, i)==I(:, j));
    end
end
% Nu(S==0) = 4;
Nu(S==1) = 3;
Nu((S==2)|(S==3)) = 2; % why? :)
Nu(S==6) = 1;
toc;

对于N=189225arrayfun在我的电脑上占用14.73秒,但总和只需0.04秒。

编辑:处理不同数量的列

以下是对上述代码的修改。现在我们也可以在每一行中拥有唯一值的位置!这个问题没有:)问题,可以用于更多的列。我的电脑上还有0.04秒的189225行。

tic;
uniq = true(N, 4);
for i=1:3
    for j=(i+1):4
          uniq(I(:, i)==I(:, j), j) = false;
    end
end
Nu = sum(uniq, 2);
toc;

修改(2):与EBHanswer的比较

过了一段时间,我需要这个用于另一个问题,我想要在每行矩阵中具有不同列数的独特元素的数量。所以我将我的代码与EBH进行了比较,看看他们的代码是否更快。我在矩阵上运行了两个代码,行数从10K到100K,列从6到60.结果是3次不同运行的花费时间(以秒为单位)的平均值:

enter image description here

我在2016a测试了这一点,并且在最新版本的MATLAB中for循环的性能有了显着的提高。因此,如果您想在旧版本中运行它,您可能需要自己进行比较。

答案 2 :(得分:1)

这是一种没有循环的超快速方法:

accumarray(repmat(1:size(I,1),1,size(I,2)).',I(:),[],@(x) numel(unique(x)))

这将为您提供矢量大小N,其中元素k是I(k,:)中唯一元素的数量。