我有一个 250 -by- 200 的大矩阵。其内部是 50 -by- 50 较小 5 -by- 4 矩阵。
重塑矩阵的最佳方法是什么,使2500 5 -by- 4 较小的矩阵相互水平对齐?因此,大矩阵的结束维度应 5 -by- 10000 。
答案 0 :(得分:2)
您可以使用mat2cell
,然后使用reshape
,最后使用cell2mat
返回矩阵。出于演示目的,我使用了变量n
和m
。它们对于你的矩阵来说都是50。
以下代码按照您在评论中阐明的方式进行排序:
n = 3; % rows
m = 2; % columns
A = reshape(1:20,[5,4]); % generate some data
M = repmat(A,n,m); % create the large matrix
X = mat2cell(M,repmat(5,1,n),repmat(4,1,m))
X = reshape(X.',1,[])
X = cell2mat(X)
注意: reshape
按列操作。因此,在使用X
之前,我们需要使用.'
或transpose
转置reshape
,如上面的代码所示。
答案 1 :(得分:2)
Matlab的reshape
函数非常方便(快速),但总是读取和写入完整的列。因此,对于您的问题,还需要一些额外的步骤。
以下是如何做到这一点:
m = 5 % columns of submatrix
n = 4 % rows of submatrix
k = 50 % num submatrixes in matrix column
l = 50 % num submatrixes in matrix row
A = rand(m*k,n*l); % rand(250,200)
将矩阵重新整形为四维矩阵(尺寸x1,x2,x3,x4),其中每个子矩阵位于x1-x3平面中。然后,原始矩阵中的子矩阵列在x2方向上,子矩阵在x4方向上行。
B = reshape(A,[m,k,n,l]); % [4,50,5,50]
置换('转置')4D矩阵,以便每个子矩阵位于x1-x2平面中。 (reshape
首先读取列,然后读取行,然后读取第3维等。)
C = permute(B,[1,3,4,2]); % For column-wise reshaping, use [1,3,2,4]
将4D矩阵重塑为所需的2D输出矩阵。
D = reshape(C,m,[]);
答案 2 :(得分:1)
以为我会添加另一种使用索引和一个内置函数zeros
的方法。也许这种方式不会有任何不必要的错误检查或重塑操作。事实证明它更有效(见下文)。
%submatrix size
m = 5;
n = 4;
%repeated submatrix rows and cols
rep_rows = 50;
rep_cols = 50;
% big matrix
A = rand(m * rep_rows, n * rep_cols);
% create new matrix
C = zeros(m, (n * rep_cols) * rep_rows);
for k = 1:rep_rows
ind_cols = (n * rep_cols) * (k - 1) + 1: (n * rep_cols) * k;
ind_rows = m * (k - 1) + 1: m * k;
C(:, ind_cols) = A(ind_rows, :);
end
我决定在这里给出三个答案,并发现这种方法要快得多。这是测试代码:
% Bastian's approach
m = 5; % columns of submatrix
n = 4; % rows of submatrix
k = 50; % num submatrixes in matrix column
l = 50; % num submatrixes in matrix row
A = rand(m*k,n*l); % rand(250,200)
% start timing
tic
B = reshape(A,[m,k,n,l]); % [4,50,5,50]
C = permute(B,[1,3,4,2]); % For column-wise reshaping, use [1,3,2,4]
D = reshape(C,m,[]);
toc
% stop timing
disp(' ^^^ Bastian');
% Matt's approach
n = 50; % rows
m = 50; % columns
% start timing
tic
X = mat2cell(A,repmat(5,1,n),repmat(4,1,m));
X = reshape(X.',1,[]);
X = cell2mat(X);
toc
% stop timing
disp(' ^^^ Matt');
% ChisholmKyle
m = 5;
n = 4;
rep_rows = 50;
rep_cols = 50;
% start timing
tic
C = zeros(m, (n * rep_cols) * rep_rows);
for k = 1:rep_rows
ind_cols = (n * rep_cols) * (k - 1) + 1: (n * rep_cols) * k;
ind_rows = m * (k - 1) + 1: m * k;
C(:,ind_cols) = A(ind_rows, :);
end
toc
% stop timing
disp(' ^^^ this approach');
这是我机器上的输出:
Elapsed time is 0.004038 seconds.
^^^ Bastian
Elapsed time is 0.020217 seconds.
^^^ Matt
Elapsed time is 0.000604 seconds.
^^^ this approach