我目前有一个数组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]]
但这只是给了我原来的矩阵。
我目前有一个数组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]]
但这只是给了我原来的矩阵。
基本上,你需要开始思考如何重新组织你的矩阵。
从
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)
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{:}];
这是我对这个问题的:
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)));
这是一个稍快一点。
+1:不错(尽管我担心@Rasman在这种情况下不能被打败:) –
@RodyOldenhuis我也这么认为,但有一点修补我的版本可以得到更整洁;)请参阅我的编辑。 –
+1第二个也很有趣,我很惊讶它甚至有效!逻辑索引通常需要与矩阵大小相同的掩码:http://www.mathworks.com/help/matlab/math/matrix-indexing.html#bq7egb6-1 – Amro
+1伟大的解决方案。我不知道你可以做'A(:,:)'! – Dan
+1:是的,绝对是最好的选择。不会赢得任何可读性的奖品,但有意见:) –
@RodyOldenhuis不幸的是,可读性和数学很少齐头并进。 – Rasman