【问题标题】:split long 2D matrix into the third dimension将长二维矩阵拆分为第三维
【发布时间】:2010-11-26 07:54:04
【问题描述】:

假设我有以下矩阵:

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

我想提取每 2 行并将它们放入第三维,所以结果会是这样的:

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/..(注意矩阵大小而step必须是参数)

% 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

【问题讨论】:

    标签: matlab matrix multidimensional-array vectorization


    【解决方案1】:

    这是使用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 的方式)索引矩阵?
    • MATLAB 矩阵元素的线性索引始终遵循列优先顺序。如果要沿行访问元素,则必须先转置矩阵,然后再执行线性索引。这就是为什么我在上述解决方案中将A' 作为 RESHAPE 的第一个参数。有关 MATLAB 中的矩阵索引的更多信息,请查看此链接:mathworks.com/company/newsletters/digest/sept01/matrix.html
    【解决方案2】:

    这是一个带有 reshapepermute 的单行代码,但没有转置输入数组 -

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

    ,其中newR3D 数组输出中的行数。


    基准测试

    本部分将本文中提出的方法与other solution with reshape, permute & transpose 的性能进行比较。数据大小与问题中列出的数据大小成比例。因此,A 的大小为 60000 x 300,我们将对其进行拆分,使 3D 输出具有 200 rows,因此 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.
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-19
      • 1970-01-01
      • 1970-01-01
      • 2017-03-04
      • 2017-12-22
      • 2023-01-11
      相关资源
      最近更新 更多