简体   繁体   English

MATLAB / Octave:使用索引数组递增数组

[英]MATLAB / Octave : Increment array with an array of indexes

I am struggling to optimize a piece of code. 我正在努力优化一段代码。 I will have to deal with many numbers (millions) and my code is running slow. 我将不得不处理许多数字(数百万),我的代码运行缓慢。 Let's suppose that we have the matrix 3x3: 我们假设我们有矩阵3x3:

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

I want to know how many elements are in the intervals [0, 3), [3, 6) and [6, 9). 我想知道区间[0,3],[3,6]和[6,9]中有多少元素。 Therefor, i need a matrix 1x3 : 因此,我需要一个矩阵1x3:

p = [ 2 3 4 ];

My code is : 我的代码是:

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

I want to do it without for loops, but the code : 我想没有for循环,但代码:

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

Outputs : 产出:

p = 1 1 1

Any ideas why? 有什么想法吗? And how can i correct this issue? 我该如何纠正这个问题?

What you are implementing is a histogram: 你正在实现的是直方图:

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

It returns p=[2,3,3,1] because it implicitly creates an interval [9,inf) 它返回p=[2,3,3,1]因为它隐式地创建了一个区间[9,inf]

To explain the indexing problem. 解释索引问题。 Multiple assignments to the same index are not supported in MATLAB. MATLAB不支持对同一索引进行多次赋值。 They always take the last assignment: 他们总是接受最后的任务:

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

And for the increment operator, the same rules apply. 对于增量运算符,适用相同的规则。 It behaves like: 它表现得像:

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

For the general case of such an multi-assignment, you can use accumarray: 对于这种多任务的一般情况,您可以使用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]

Histogram bin counts 直方图箱计数

As Daniel writes in his answer, you're computing counts of values in histogram bins. 正如丹尼尔在他的回答中写道,你正在计算直方图箱中值的计数。 An alternative method to hist is using the newer histcounts command (recommended for newer Matlab versions). hist的另一种方法是使用较新的histcounts命令(推荐用于较新的Matlab版本)。

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

%// p = 2     3     4

Matrix relation operators followed by non-zero element count 矩阵关系运算符后跟非零元素计数

You could also make use of matrix relational operators followed by nnz command to count non-zero elements: 您还可以使用矩阵关系运算符,然后使用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

"Quickest?" “最快?”

From some quick tic / toc tests, it seems that—on my system (running Matlab R2014b)—the latter nnz method is: 从一些快速的tic / toc测试来看,似乎在我的系统上(运行Matlab R2014b) - 后一种nnz方法是:

  • ~3-4 times quicker than the histcounts method. histcounts方法快3-4倍。
  • ~5-6 times quicker than the histogram method using the older hist command. 比使用旧的hist命令的直方图方法快5-6倍。

I have not tried, however, to see how this scales as A becomes larger, in case this is the case for your application. 但是,我没有尝试过看A如何变大,以防你的应用程序出现这种情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM