我目前有一个阵列A,其尺寸为N x t x t。我想创建一个形式为:
的二维矩阵N x tB = [ A[:,1,1] A[:,2,2],...,A[:,t,t]]
显然,我能做到的两种方法是完全写出来(因为t很大而不切实际)和循环(可能很慢)。有没有办法没有循环这样做。我认为如果我这样做会起作用:
B = A[:,[1:end],[1:end]]
但这只是让我回到了原始矩阵。
答案 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{:}];