MATLAB:使用列表访问多维数组的元素

发布于 2024-11-16 11:44:10 字数 372 浏览 2 评论 0原文

我有一个 d 维数组 A 和长度等于 d 的向量 inds 。我想访问 indsA 的值。

理想情况下,我会做类似 A(*inds) 的事情(借用 Python 的解包语法)。我不知道如何在 MATLAB 中执行此操作。

如果我这样做 A(inds) 我实际上会从 A 中得到 d 个单独的值,这不是我想要的。我想要的是 inds 的元素 i 成为函数调用 A() 中的第 i 个参数。

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().

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

吃不饱 2024-11-23 11:44:10

一种解决方案是创建一个 逗号分隔列表从你的下标索引inds向量中。您可以通过使用 NUM2CELL 将其转换为元胞数组来实现此目的,然后在索引 A 时使用 {:} 语法:

inds = num2cell(inds);
value = A(inds{:});

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{:});
忆沫 2024-11-23 11:44:10

我认为这个工具可能会帮助你:

如果你有一个像 R = rand(5,10,15,20) 这样的 ND 矩阵,并且你想以特定模式访问元素,你可以使用 spindex 来访问相同的输出形状作为输入访问。因此,如果您有 size(i1) = [5,5,5]、size(i2) = [5,5,5] 等,则 size(spindex(R,i1,i2,i3,i4)) 也等于[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]]

您需要将下面的代码作为 spindex.m 添加到 MATLAB 路径中的某个位置。

 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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文