【问题标题】:MATLAB / Octave : Increment array with an array of indexesMATLAB / Octave:具有索引数组的增量数组
【发布时间】:2016-07-01 00:06:45
【问题描述】:

我正在努力优化一段代码。 我将不得不处理许多数字(数百万)并且我的代码运行缓慢。 假设我们有 3x3 矩阵:

A = [ 8 1 6; 3 5 7; 4 9 2 ];

我想知道区间 [0, 3), [3, 6) 和 [6, 9) 中有多少个元素。因此,我需要一个 1x3 矩阵:

p = [ 2 3 4 ];

我的代码是:

p = zeros(1, 3);
for i = 1 : 9
   p( floor(A / 3) + 1 ) += 1;

我想不使用 for 循环,但是代码:

p = zeros(1, 3);
p( floor(A / 3) + 1 ) += 1;

输出:

p = 1 1 1

任何想法为什么?我该如何纠正这个问题?

【问题讨论】:

    标签: arrays matlab indexing octave


    【解决方案1】:

    你正在实现的是一个直方图:

    p=histc(A(:),[0,3,6,9]); %For MATLAB 2014b or newer use histcounts instead
    

    它返回p=[2,3,3,1],因为它隐式创建了一个区间 [9,inf)

    解释索引问题。 MATLAB 不支持对同一索引进行多次赋值。他们总是接最后一个任务:

    x=zeros(3,1)
    x([1,1,2,1])=[1,2,3,4] %results in x(1)=4
    

    对于增量运算符,同样的规则适用。它的行为类似于:

    x([1,1,1,1])=x([1,1,1,1])+1
    

    对于这种多赋值的一般情况,可以使用accumarray:

    %assume you want x([1,1,2,1])=[1,2,3,4]
    accumarray([1,1,1,1].',[1,2,3,4].')
    %results in [7,3]
    

    【讨论】:

      【解决方案2】:

      直方图 bin 计数

      正如丹尼尔在他的回答中所写,您正在计算直方图箱中的值的计数。 hist 的替代方法是使用较新的 histcounts 命令(推荐用于较新的 Matlab 版本)。

      A = [ 8 1 6; 3 5 7; 4 9 2 ];
      [p, ~, ~] = histcounts(A, 0:3:9);
      
      %// p = 2     3     4
      

      矩阵关系运算符后跟非零元素计数

      您还可以使用矩阵关系运算符,后跟nnz 命令来计算非零元素:

      A = [ 8 1 6; 3 5 7; 4 9 2 ];
      p = [nnz(A < 3);
          nnz(A >= 3 & A < 6);
          nnz(A >= 6)];         %// alternatively nnz(A >= 6 & A < 9) for the last entry
      
      %// ...
      
      p =
      
           2
           3
           4
      

      “最快?”

      从一些快速的tic/toc 测试看来,在我的系统上(运行 Matlab R2014b)后一种nnz 方法是:

      • histcounts 方法快 3-4 倍。
      • 比使用旧的 hist 命令的直方图方法快 5-6 倍。

      但是,我还没有尝试查看随着 A 变大时它如何扩展,以防您的应用程序出现这种情况。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-03-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-23
        • 1970-01-01
        • 1970-01-01
        • 2018-09-14
        相关资源
        最近更新 更多