将长的二维矩阵分割成第三个维度。

13

假设我有以下矩阵:

A = randi(10, [6 3])
     7    10     3
     5     5     7
    10     5     1
     6     5    10
     4     9     1
     4    10     1

我想提取每两行并将它们放在第三维中,结果应该像这样:

B(:,:,1) =
     7    10     3
     5     5     7
B(:,:,2) =
    10     5     1
     6     5    10
B(:,:,3) =
     4     9     1
     4    10     1

我显然可以用for循环来实现这个操作,但我想知道如何使用 permute / reshape / .. 来更加优雅地实现一行代码(请注意矩阵大小和步长必须是参数)

% params
step = 5;
r = 15;
c = 3;

% data
A = randi(10, [r c]);
B = zeros(step, c, r/step); % assuming step evenly divides r

% fill
counter = 1;
for i=1:step:r
    B(:,:,counter) = A(i:i+step-1, :);
    counter = counter + 1;
end
2个回答

13

这是一个使用 reshapepermute 的一行解决方案:

C = 3;          % Number of columns
R = 6;          % Number of rows
newR = 2;       % New number of rows
A = randi(10, [R C]);  % 6-by-3 array of random integers
B = permute(reshape(A.', [C newR R/newR]), [2 1 3]);

这当然需要 newR 可以被 R 整除。


正是我所需要的,谢谢! 顺便问一下,如何按行主序而不是列主序(MATLAB的方式)对矩阵进行索引? - Amro
1
MATLAB矩阵元素的线性索引始终遵循列主序。如果要访问沿行的元素,则必须在执行线性索引之前先转置矩阵。这就是为什么我在上面的解决方案中将A'作为第一个参数传递给RESHAPE的原因。有关MATLAB中矩阵索引的更多信息,请查看此链接:http://www.mathworks.com/company/newsletters/digest/sept01/matrix.html - gnovice

2

这是一个使用reshapepermute的一行代码,但不需要对输入数组进行转置操作 -

out = permute(reshape(A,newR,size(A,1)/newR,[]),[1 3 2]);

在这个代码中,newR3D数组输出的行数。


基准测试

本节将在性能方面比较本文中提出的方法与其他使用reshape、permute和transpose的解决方法。数据大小按比例膨胀到问题中列出的大小。因此,A的大小为60000 x 300,我们将其分割成200行3D输出,因此dim-3将有300个条目。

基准测试代码 -

%// Input
A = randi(10, [60000 300]); %// 2D matrix
newR = 200;                 %// New number of rows

%// Warm up tic/toc.
for k = 1:50000
    tic(); elapsed = toc();
end

N_iter = 5; %// Number of iterations for each approach to run with

disp('---------------------- With PERMUTE, RESHAPE & TRANSPOSE')
tic
for iter = 1:N_iter
    [R,C] = size(A);
    B = permute(reshape(A',[C newR R/newR]),[2 1 3]); %//'
end
toc, clear B R C iter

disp('---------------------- With PERMUTE & RESHAPE')
tic
for iter = 1:N_iter
    out = permute(reshape(A,newR,size(A,1)/newR,[]),[1 3 2]);
end
toc

输出 -

---------------------- With PERMUTE, RESHAPE & TRANSPOSE
Elapsed time is 2.236350 seconds.
---------------------- With PERMUTE & RESHAPE
Elapsed time is 1.049184 seconds.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接