[英]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
方法是:
histcounts
method. 比histcounts
方法快3-4倍。 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.