Matlab 大于阈值的值的数目

Matlab 大于阈值的值的数目,matlab,indexing,Matlab,Indexing,我有一个矩阵a。现在我想找到大于5的元素数和它们对应的指数。如何在不使用for循环的情况下在matlab中解决这个问题 例如,如果A=[1 4 6 8 9 5 6 8 9],: 元素数>5:6 索引:[3 4 5 7 8 9] 您使用查找: index = find(A>5); numberOfElements = length(index); 您可以使用sum,它允许您通过一个命令获得元素的数量: numberOfElements = sum(A>5); 你真的需要显式索引吗

我有一个矩阵
a
。现在我想找到大于5的元素数和它们对应的指数。如何在不使用for循环的情况下在matlab中解决这个问题

例如,如果
A=[1 4 6 8 9 5 6 8 9],

  • 元素数>5:6
  • 索引:
    [3 4 5 7 8 9]

    • 您使用
      查找

      index = find(A>5);
      numberOfElements = length(index);
      

      您可以使用
      sum
      ,它允许您通过一个命令获得元素的数量:

      numberOfElements = sum(A>5);
      
      你真的需要显式索引吗?因为逻辑矩阵
      A>5
      也可以用作索引(通常比使用
      find
      进行索引更有效):

      完整性:使用逻辑索引与使用常规索引相同:

      >> A(A>5)
      ans = 
           6  8  9  6  8  9
      

      基于上述与Rody的讨论,这里有一个简单的基准测试,它在MATLAB中测试整数索引与逻辑数组索引的速度。我想说的是一件非常重要的事情,因为“矢量化”的MATLAB主要是关于索引的。所以

      % random data
      a = rand(10^7, 1);
      
      % threashold - how much data meets the a>threashold criterion
      % This determines the total indexing time - the more data we extract from a,
      % the longer it takes.
      % In this example - small threashold meaning most data in a 
      % will meet the criterion.
      threashold = 0.08;
      
      % prepare logical and integer indices (note the uint32 cast)
      index_logical = a>threashold;
      index_integer = uint32(find(index_logical));
      
      % logical indexing of a
      tic
      for i=1:10
          b = a(index_logical);
      end
      toc
      
      % integer indexing of a
      tic
      for i=1:10
          b = a(index_integer);
      end
      toc
      
      在我的电脑上,结果是

      Elapsed time is 0.755399 seconds.
      Elapsed time is 0.728462 seconds.
      
      这意味着这两种方法的性能几乎相同-这就是我选择示例
      threashold
      的方式。这很有趣,因为
      index_integer
      数组几乎要大4倍

      index_integer       9198678x1              36794712  uint32               
      index_logical      10000000x1              10000000  logical              
      
      对于
      threashold
      的较大值,整数索引速度更快。
      threashold=0.5的结果:

      Elapsed time is 0.687044 seconds. (logical)
      Elapsed time is 0.296044 seconds. (integer)
      
      除非我在这里做错了什么,否则整数索引在大多数情况下似乎是最快的

      但是,包括在测试中创建指数会产生非常不同的结果:

      a = rand(1e7, 1);    
      threshold = 0.5;
      
      % logical 
      tic
      for i=1:10
          inds = a>threshold;
          b = a(inds);
      end
      toc
      
      % double
      tic
      for i=1:10
          inds = find(a>threshold);
          b = a(inds);
      end
      toc
      
      % integer 
      tic
      for i=1:10
          inds = uint32(find(a>threshold));
          b = a(inds);
      end
      toc
      
      结果(罗迪):

      结果(angainor):

      因此,使用整数进行索引时,实际的索引速度似乎更快,但从前到后,逻辑索引的性能要好得多

      然而,最后两种方法之间的运行时差异是出乎意料的——看起来Matlab的内部要么没有将双精度转换为整数,要么在执行实际索引之前对每个元素执行错误检查。否则,我们几乎看不到double和integer方法之间的区别

      编辑在我看来,有两个选项:

      • 在索引调用之前,matlab将双索引显式转换为uint32索引(与整数测试中的做法非常相似)
      • matlab在索引调用期间动态传递double并执行double->int转换

      第二个选项应该更快,因为我们只需要读取双索引一次。在显式转换测试中,我们必须读取双索引,写入整数索引,然后在实际索引期间再次读取整数索引。所以matlab应该更快。。。为什么不呢?

      Rody,关于
      sum/find
      ,你可能是对的。但是,无论如何都必须存储索引。否则,您将计算两次A>5。另外,
      sum
      可能比
      find
      快,但是
      A(整数索引)
      A(逻辑索引)
      快,因为
      logical\u索引
      是数据大小的0-1向量,而
      整数索引
      只保存必要的值。@angainor:当然,只要使用
      index=A>5;numEls=总和(指数)。另外:逻辑索引比使用
      find
      索引更快;你自己试试看。至于内存开销,这实际上取决于--
      find
      返回双精度(每个条目64位),而逻辑索引是布尔值(每个条目8位,甚至可能是1位)--在这方面,无法对这两个值进行全面说明。您可以将双精度转换为uint(16/32/64)-实际上,您应该这样做,因为在性能方面,使用双精度索引是一个相当糟糕的主意。逻辑当前为(2011b+)1字节。在早期版本中,它们是4个字节:)但是是的,这取决于。。有没有办法在SO上发布带有基准的代码?我想我可以用我写的基准代码来回答这个问题。或者有其他选择吗?@angainor:聊天室:)但实际上,我认为答案是最佳实践。我还怀疑Matlab隐式地将双索引转换为
      uint
      ,我怀疑这是性能差异的部分原因。+1:测试很好,尽管我很想看看索引的创建如何影响时间。介意我编辑吗?@RodyOldenhuis哦,去吧。我希望我们在这里得出有趣的结论。@RodyOldenhuis的第一个测试有一个
      b=a()
      语句,我想这是错误的。这会影响你的结果吗?是的,根据我的经验,matlab显式地将double转换为int(通过一个check-how-else?)。这就是为什么有时使用显式整数更好。哎哟!!复制酶错误传播的经典案例。现在修复:)哇,你的结果比我的好得多…为什么?你们有什么处理器?我的笔记本电脑上有一个Intel(R)Core(TM)i3-2310M处理器@2.10GHz。非常糟糕,双核。
      a = rand(1e7, 1);    
      threshold = 0.5;
      
      % logical 
      tic
      for i=1:10
          inds = a>threshold;
          b = a(inds);
      end
      toc
      
      % double
      tic
      for i=1:10
          inds = find(a>threshold);
          b = a(inds);
      end
      toc
      
      % integer 
      tic
      for i=1:10
          inds = uint32(find(a>threshold));
          b = a(inds);
      end
      toc
      
      Elapsed time is 1.945478 seconds. (logical)
      Elapsed time is 3.233831 seconds. (double)
      Elapsed time is 3.508009 seconds. (integer)
      
      Elapsed time is 1.440018 seconds. (logical)
      Elapsed time is 1.851225 seconds. (double)
      Elapsed time is 1.726806 seconds. (integer)