从3d矩阵中提取多个列

时间:2013-06-26 13:14:59

标签: matlab loops matrix matrix-indexing

我目前有一个阵列A,其尺寸为N x t x t。我想创建一个形式为:

的二维矩阵N x t
B = [ A[:,1,1] A[:,2,2],...,A[:,t,t]]

显然,我能做到的两种方法是完全写出来(因为t很大而不切实际)和循环(可能很慢)。有没有办法没有循环这样做。我认为如果我这样做会起作用:

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

但这只是让我回到了原始矩阵。

3 个答案:

答案 0 :(得分: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会产生您的解决方案

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

在一般格式中,您可以这样做:

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

编辑:

Amro基本上只是让我感到羞耻。这个想法仍然是一样的,由于end

,它变得更具可读性

因此使用:

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

答案 1 :(得分: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)));

这有点快。

答案 2 :(得分:1)

MATLAB在矢量和矩阵方面相当不错,但是对于"通用数组而言#34;你经常需要切换到"一般方法"。当你习惯于操纵矩阵/向量时,这看起来非常笨拙,落后并且根本不方便(实际上这是非常可靠的原因,但是那个' sa讨论另一次:)。

下面的版本通过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{:}];