问题
I have a d-dimensional array, A, and vector inds with length equal to d. I would like to access the value of A at inds.
Ideally, I'd do something like A(*inds) (borrowing the unpacking syntax from Python). I'm not sure how to do this in MATLAB.
If I do A(inds) I actually get d separate values from A, which is not what I want. What I want is for element i of inds to be the ith parameter in the function call A().
回答1:
One solution is to create a comma-separated list out of your vector of subscripted indices inds
. You can do this by converting it to a cell array using NUM2CELL, then using the {:}
syntax when indexing A
:
inds = num2cell(inds);
value = A(inds{:});
回答2:
I think this tool might help you:
if you have an ND matrix like R = rand(5,10,15,20), and you want to access elements in a particular pattern, you can use spindex to access the output in the same shape as the input access. So if you have size(i1) = [5,5,5], size(i2) = [5,5,5], etc. Then size(spindex(R,i1,i2,i3,i4)) also equals [5,5,5].
%#example:
z = reshape(1:(5^4),[5,5,5,5]);
zid1 = [1,1,5];
zid2 = [1,2,5];
zid3 = [1,3,5];
zid4 = [1,4,5];
zOut = spindex(z,zid1,zid2,zid3,zid4)
%# should be like [1,431,625]
zid1 = [1,2;3,4];
zid2 = [1,1;1,1];
zid3 = [1,1;1,1];
zid4 = [1,1;1,1];
zOut = spindex(z,zid1,zid2,zid3,zid4)
%%# should be like [[1,2];[3,4]]
you will need to add the code below as spindex.m to a location in your MATLAB path.
function outM = spindex(inM,varargin)
%function outM = spindex(inM,varargin)
%
%returns a matrix indexed from inM via index variables contained in varargin
%useful for retreiving multiple values from a large multidimensional matrix
%
%
%inM is an N-d matrix
%the index variables stored in varargin must be as numerous as the number of dimensions in inM
%each index variable must be identical in size
%
%example:
%
%z = reshape(1:(5^4),[5,5,5,5]);
%zid1 = [1,1,5];
%zid2 = [1,2,5];
%zid3 = [1,3,5];
%zid4 = [1,4,5];
%zOut = spindex(z,zid1,zid2,zid3,zid4)
%% should be like [1,431,625]
%zid1 = [1,2;3,4];
%zid2 = [1,1;1,1];
%zid3 = [1,1;1,1];
%zid4 = [1,1;1,1];
%zOut = spindex(z,zid1,zid2,zid3,zid4)
%% should be like [[1,2];[3,4]]
sz = size(inM);
ndim = length(sz);
if((ndim == 2) & (sz(2) ==1)) % ndim always returns at least 2
ndim =1;
end
if(nargin ~= (ndim +1))
extraDims = setdiff(1:(nargin - 1),1:ndim);
for iExtraDim = extraDims
if(any(varargin{iExtraDim}~=1))
error('must have as many indicies as dimensions\n');
end
end
end
szid = size(varargin{1});
for i = 1:ndim
szid2 = size(varargin{i});
if(any(szid2 ~= szid))
error('indicies must have identical shape');
end
ndIdxs(:,i) = varargin{i}(:);
end
if(ndim == 1)
idxs = ndIdxs(:,1);
else
idxs = myNDsub2ind(size(inM),ndIdxs);
end
outM = nan(1,length(idxs));
outM(find(not(isnan(idxs)))) = inM(idxs(find(not(isnan(idxs)))));
outM = reshape(outM,size(varargin{1}));
function ndx = myNDsub2ind(siz,subs)
%function ndx = NDsub2ind(siz,subs)
%-------------------------------
%works more smoothly when the dimensionality of the mtrx is unknown
%siz should be like [10 10 4 5] if subs is like
% 9 8 3 5
% 1 1 1 1
% 10 10 4 5
% 5 8 3 3
%
% siz will be rotated for you if submit a row vec instead a col vector
% example: NDsub2ind([10 10 4 5],[[9,8,3,5];[1,1,1,1]])
%----------------------------------------------
if(size(siz,1) > 1) && (size(siz,2) > 1)
error('the siz variable must be a vector');
end
if((size(subs,1) ~= 1) && (size(subs,2) == 1))
subs = subs';
end
siz = siz(:)';
if length(siz)<2
error('MATLAB:sub2ind:InvalidSize',...
'Size vector must have at least 2 elements.');
end
if ((length(siz) ~= size(subs,2)))
error('NDsub2ind: length(siz) must = size(subs,2)');
end
nPoints = size(subs,1);
%Compute linear indices
k = [1 cumprod(siz(1:end-1))];
ndx = ones(nPoints,1);
s = size(subs); %For size comparison
for i = 1:length(siz),
v = subs;
fNaN = find( (v(:,i) < 1) | (v(:,i) > siz(i)) );
%Verify subscripts are within range
v(fNaN,i) = nan;
ndx = ndx + (v(:,i)-1)*k(i);
end
来源:https://stackoverflow.com/questions/6390766/matlab-accessing-an-element-of-a-multidimensional-array-with-a-list