diviser longue matrice 2D dans la troisième dimension
-
21-09-2019 - |
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
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.