2016-03-15 30 views
3

我正在努力优化一段代码。 我将不得不处理很多数字(百万),我的代码运行缓慢。 让我们假设我们有3×3矩阵:MATLAB/Octave:带有索引数组的递增数组

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

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

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 

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

回答

2

要实现什么是直方图:

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] 
1

直方图箱数

正如丹尼尔在他的回答写道,你正在计算直方图中的数值。 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倍。
  • 〜5-6比使用旧hist命令直方图方法更快倍。

我没试过,不过,怎么看这个规模s如A变大,以防您的应用程序出现这种情况。