2013-06-26 141 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