Extracting from vector to multidimensional array using indices provided
2 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
Andris Cerins
am 14 Apr. 2020
Kommentiert: Andris Cerins
am 18 Apr. 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 Kommentare
Akzeptierte Antwort
Stephen23
am 17 Apr. 2020
Bearbeitet: Stephen23
am 17 Apr. 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
1 Kommentar
Weitere Antworten (1)
Guru Mohanty
am 17 Apr. 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 Kommentar
Stephen23
am 17 Apr. 2020
Bearbeitet: Stephen23
am 17 Apr. 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.
Siehe auch
Kategorien
Mehr zu Structures finden Sie in Help Center und File Exchange
Produkte
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!