Selecting data from a dynamically named ND array
조회 수: 6 (최근 30일)
이전 댓글 표시
I have a structure with fields of various dimensions - typically between 3 and 6. Each of the fields has one dimension that represents a sampling instance, but in some fields it is dimension 2, in others dimension 3 or 4. I need to extract a subset of the data from each of the fields by selecting samples along the relevant dimension, so if all of the fields were, say, 4D and the sampling dimension was 2 with ix as the selection, I could use:
flds = fieldnames(S.(inst))
for i = 1:numel(flds)
fld = flds{i};
S.(inst).(fld) = S.(inst).(fld)(:,ix,:,:);
clear fld
end; clear i
I can easily check the number of dimensions of the field and I can work out which dimension of the field I need to sample along, but I then end up with something like:
flds = fieldnames(S.(inst))
for i = 1:numel(flds)
fld = flds{i};
ndims = numel(size(S.(inst).(fld));
idir = find(size(S.(inst).(fld)) == Nsamples); % where Nsamples is the number of samples
if ndims == 3
if idir == 1
S.(inst).(fld) = S.(inst).(fld)(ix,:,:);
elseif idir == 2
S.(inst).(fld) = S.(inst).(fld)(:,ix,:);
else
S.(inst).(fld) = S.(inst).(fld)(:,:,ix;
end
elseif ndims == 4
if idir == 1
S.(inst).(fld) = S.(inst).(fld)(ix,:,:,:)
elseif idir == 2
% etc
% etc
end
clear fld
end; clear i
I wondered whether anyone could suggest a more elegant solution? I was thinking that it would be possible to dynamically generate the data selection (:,ix,:,:) as a text string and use it with eval, but I'm not sure that works with the dynamic naming of variables.
Any thoughts?
댓글 수: 0
채택된 답변
Stephen23
2017년 5월 18일
편집: Stephen23
2018년 11월 6일
For a start you might like to read this (if you want to write better code, then it can help you):
And then to solve your problem you do not need to write lots of if-s or use eval, in fact you can do solve your quite simply by creating a cell array of indices and using that to generate a comma-separated list:
>> X = randi(9,1,2,3,4);
>> C = {':',':',2,':'};
>> X(C{:})
ans(:,:,1,1) =
1 1
ans(:,:,1,2) =
8 2
ans(:,:,1,3) =
3 8
ans(:,:,1,4) =
2 4
Another alternative is to call subsref directly. The function subsref is what MATLAB uses to index into variables, but you can also call it directly. All you need to do is create a suitable structure input, it is not that hard but you should play around with it to understand how it works. For example:
>> subsref(X,substruct('()',C))
ans(:,:,1,1) =
1 1
ans(:,:,1,2) =
8 2
ans(:,:,1,3) =
3 8
ans(:,:,1,4) =
2 4
Clearly it is pretty trivial to construct that cell array: something like this (untested):
C = repmat({':'},1,totdim);
C{ixdim} = ix;
댓글 수: 2
추가 답변 (0개)
참고 항목
카테고리
Help Center 및 File Exchange에서 Logical에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!