【问题标题】:How to find number of unique elements in each row of a matrix?如何在矩阵的每一行中找到唯一元素的数量?
【发布时间】:2017-11-25 15:44:58
【问题描述】:

我正在尝试实现某种插值算法。 I 是一个 N*4 矩阵,包含 N 其他点的周围点的索引。但是I 的每一行中的元素可能不是唯一的,这意味着它们中的两个或多个可能引用一个单独的点。我想知道每行中有多少个唯一索引可用,并且我想尽快完成,因为N 很大!

【问题讨论】:

    标签: matlab matrix unique


    【解决方案1】:

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

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

    索引数组被转置,结果是一个列向量。

    【讨论】:

    • 请您检查我的答案。 mamnoon misham ;)
    • 如何编辑上述语法,使其不将零视为唯一元素?
    【解决方案2】:

    这是一种无需循环的超快速方法:

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

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

    【讨论】:

      【解决方案3】:

      好吧,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 秒。

      编辑:注意不同数量的列

      这是对上面代码的修改。现在我们也可以在每一行中都有唯一值的位置!这个没有:) 的问题,可以用于更多的列。 189225 行在我的 PC 上仍然需要 0.04 秒。

      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 次不同运行的平均花费时间(以秒为单位):

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-10
        • 1970-01-01
        • 2014-08-26
        • 1970-01-01
        • 2021-06-12
        • 1970-01-01
        相关资源
        最近更新 更多