2016-03-15 28 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變大,以防您的應用程序出現這種情況。