Question

Dire que j'ai la matrice suivante:

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

Et je voudrais extraire toutes les 2 rangées et les mettre dans la troisième dimension, de sorte que le résultat serait comme:

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

Je ne peux évidemment le faire avec une boucle, se demandant comment le faire plus élégamment une doublure en utilisant permute / Reshape / .. (note taille de la matrice et l'étape doit être paramètres)

% 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
Était-ce utile?

La solution

Voici une solution d'une ligne en utilisant reshape et permute :

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]);

Bien sûr, cela exige que newR divise uniformément dans R.

Autres conseils

Voici une seule ligne avec reshape et permute , mais sans transposer le tableau d'entrée -

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

, où newR est le nombre de lignes de la sortie du réseau de 3D.


Analyse comparative

Cette section compare le aproche proposé dans ce poste contre le other solution with reshape, permute & transpose sur la performance. Les datasizes sont gonflés à la proportionnalité ceux énumérés dans la question. Ainsi, A est 60000 x 300 taille et nous diviser de telle sorte que la sortie 3D aurait 200 rows et dim-3 aurait ainsi les entrées de 300.

Code Benchmarking -

%// 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

Sortie -

---------------------- With PERMUTE, RESHAPE & TRANSPOSE
Elapsed time is 2.236350 seconds.
---------------------- With PERMUTE & RESHAPE
Elapsed time is 1.049184 seconds.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top