2013-06-26 142 views
4

我目前有一個數組A,它的維數爲N x t x t。我想創建形式的二維矩陣,N×T的,:從3d矩陣中提取幾列

B = [ A[:,1,1] A[:,2,2],...,A[:,t,t]] 

顯然,2種方法我能做到這一點是出在全寫入它(不實際,因爲t爲大),循環(可能慢)。有沒有辦法做到這一點沒有循環。我認爲它會工作,如果我這樣做:

B = A[:,[1:end],[1:end]] 

但這只是給了我原來的矩陣。

回答

8

基本上,你需要開始思考如何重新組織你的矩陣。

A = randn([5 3 3]); 

讓我們來看看

A(:,:) 

基本上你想你想通過遞增列1,5,9,思考它,知道T = 3,從目前列T + 1,式基本上是:

((1:3)-1)*(3+1)+1 %(or (0:2)*(3+1) + 1) 

所述的哪個插產生的溶液

A(:,((1:3)-1)*(3+1)+1) 

在一般的格式,你可以這樣做:

A(:,((1:t)-1)*(t+1)+1) 

編輯:

荷銀基本上只是把我的恥辱。這個想法仍然是相同的,它只是變得更易讀感謝end

因此使用:

A(:,1:t+1:end) 
+2

+1偉大的解決方案。我不知道你可以做'A(:,:)'! – Dan

+0

+1:是的,絕對是最好的選擇。不會贏得任何可讀性的獎品,但有意見:) –

+0

@RodyOldenhuis不幸的是,可讀性和數學很少齊頭並進。 – Rasman

1

MATLAB對於矢量和矩陣非常好,但是當涉及到「通用數組」時,您通常不得不切換到「常規方法」。當你習慣了操縱矩陣/矢量的輕鬆方式時,這看起來非常笨拙,落後並且不是很方便(實際上有非常可捍衛的理由,但這是另一次的討論:)。

通過arrayfun以下版本遍歷每個頁面(僅比大型矩陣正常循環更快),並在每一頁上呼籲diag

% "flip" the array, so that 3rd dimension becomes the 1st (rows), and 
% the 1st dimension becomes the 3rd, so that each "page" is a regular 
% matrix. You want the diagonals of all these matrices. 
b = permute(a, [3 2 1]); 

% Now "loop" through the pages, and collect the matrix diagonal for each page 
c = arrayfun(@(ii)diag(b(:,:,ii)), 1:size(b,3), 'UniformOutput', false); 

% The above will output a cell-array, which you can cast back to 
% a numeric matrix through this operation: 
A = [c{:}]; 
+0

相當於「A(:,1:t + 1:end)」;)你的意思是通用數組雖然是什麼?單元陣列?因爲你可以像矩陣那樣或多或少地索引單元陣列。 – Shaun314

+0

@ Shaun314:不,我的意思是一個不是1-或2維(矢量或矩陣)的數組,而是「N」維。 –

+0

阿got,現在有點多了:) – Shaun314

3

這是我對這個問題的:

mask = repmat(logical(permute(eye(size(A,2)), [3 1 2])), size(A,1), 1); 
newA = reshape(A(mask), size(A,1), []); 

就產生面膜,敷它並將結果重塑爲正確的形狀。

編輯:

或者更簡單:

newA = A(:, logical(eye(size(A,2)))) 

或沿着相同的路線,

newA = A(:, diag(true(size(A,2),1))); 

這是一個稍快一點。

+0

+1:不錯(儘管我擔心@Rasman在這種情況下不能被打敗:) –

+0

@RodyOldenhuis我也這麼認爲,但有一點修補我的版本可以得到更整潔;)請參閱我的編輯。 –

+0

+1第二個也很有趣,我很驚訝它甚至有效!邏輯索引通常需要與矩陣大小相同的掩碼:http://www.mathworks.com/help/matlab/math/matrix-indexing.html#bq7egb6-1 – Amro