Extracting from vector to multidimensional array using indices provided
2 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Andris Cerins
le 14 Avr 2020
Commenté : Andris Cerins
le 18 Avr 2020
Can this extraction be performed better without loops?
% data vector
data = [1 1 1 1 1 4 4 4 4 4 7 7 7 7 7 2 2 2 2 2 5 5 5 5 5 8 8 8 8 8 3 3 3 3 3 6 6 6 6 6 6 9 9 9 9 9]
% Desired output
data3d(:,:,1)
1 1 1 1 1
2 2 2 2 2
3 3 3 3 3
data3d(:,:,2)
4 4 4 4 4
5 5 5 5 5
6 6 6 6 6
data3d(:,:,3)
7 7 7 7 7
8 8 8 8 8
9 9 9 9 9
% indices for starts and ends of trials, rows are channels
dstart = [1 16 31; 6 21 36; 11 26 42]
dend = [5 20 35; 10 25 41; 15 30 46]
% note the annoying extra 6 in data
% can truncate now, dend_tr = dstart+4, or just use dstart:dstart+4
% or if target matrix pads then truncate later?
[numchannels,numsweeps] = size(dstart) %in case it is useful
% Here is how I think it would work using loops
% For all channels in that file
for ich = 1:numchannels
data_sweeps = [];
% For all sweeps in that file
for isw = 1:numsweeps
sweepdata = [];
% Get that sweep, truncate it to 5 samples (because some have extras)
sweepdata = data(dstart(ich,isw):dstart(ich,isw)+4);
% Make sweeps x samples matrix
data_sweeps(isw,:) = sweepdata;
end
% Adds each channel as a page in a 3d matrix
data3d(:,:,ich) = data_sweeps
end
0 commentaires
Réponse acceptée
Stephen23
le 17 Avr 2020
Modifié(e) : Stephen23
le 17 Avr 2020
In three lines (could be just one), no loops, and yes that extra 6 is taken into account!
>> D = [1,1,1,1,1,4,4,4,4,4,7,7,7,7,7,2,2,2,2,2,5,5,5,5,5,8,8,8,8,8,3,3,3,3,3,6,6,6,6,6,6,9,9,9,9,9];
>> S = [1,16,31;6,21,36;11,26,42];
>> E = [5,20,35;10,25,41;15,30,46];
>> F = @(s)reshape(s:s+4,[],1);
>> X = cell2mat(arrayfun(F,sort(S(:)),'uniformoutput',false));
>> A = permute(reshape(D(X),[5,3,3]),[3,1,2])
A(:,:,1) =
1 1 1 1 1
2 2 2 2 2
3 3 3 3 3
A(:,:,2) =
4 4 4 4 4
5 5 5 5 5
6 6 6 6 6
A(:,:,3) =
7 7 7 7 7
8 8 8 8 8
9 9 9 9 9
Plus de réponses (1)
Guru Mohanty
le 17 Avr 2020
I understand you are trying to extract data from a vector to multidimensional array without for loops.
It can be possible using MATLAB Array indexing. Here is a sample code for it.
% data vector
tic;
data = [1 1 1 1 1 ...
4 4 4 4 4 ...
7 7 7 7 7 ...
2 2 2 2 2 ...
5 5 5 5 5 ...
8 8 8 8 8 ...
3 3 3 3 3 ...
6 6 6 6 6 ...
9 9 9 9 9];
data=reshape(data,5,9);
dstart = [1 4 7;
2 5 8;
3 6 9];
data3d(:,:,1) = [data(:,dstart(1,1))';data(:,dstart(1,2))';data(:,dstart(1,3))'];
data3d(:,:,2) = [data(:,dstart(2,1))';data(:,dstart(2,2))';data(:,dstart(2,3))'];
data3d(:,:,3) = [data(:,dstart(3,1))';data(:,dstart(3,2))';data(:,dstart(3,3))'];
toc;
1 commentaire
Stephen23
le 17 Avr 2020
Modifié(e) : Stephen23
le 17 Avr 2020
@Guru Mohanty: your data vector is missing a 6 (as the original question points out, there are more of them). So your data vector should actually be defined as:
data = [1 1 1 1 1 ...
4 4 4 4 4 ...
7 7 7 7 7 ...
2 2 2 2 2 ...
5 5 5 5 5 ...
8 8 8 8 8 ...
3 3 3 3 3 ...
6 6 6 6 6 6 ... <- "note the annoying extra 6 in data"
9 9 9 9 9];
and then reshape fails with an error.
Using MATLAB permute instead of copy-and-pasting the same code nine times will improve your Code performance.
Voir également
Catégories
En savoir plus sur Structures dans Help Center et File Exchange
Produits
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!