【问题标题】:Matlab last dimension access on ndimensions matrixMatlab对ndimensions矩阵的最后一维访问
【发布时间】:2013-11-26 03:57:18
【问题描述】:

我有一个矩阵作为条目,它可以有多个维度:n × mn × m × pn × m × p × q 或 ...

我想做的是访问最后一个维度,例如:

data = input(:,:,1)

问题是:的数量可以改变。

【问题讨论】:

  • 可能的维数是有限的(而且很小)吗?如果是这样,您可以使用size 函数查询矩阵的大小,并使用switch 语句来处理各种情况。
  • 请注意,不建议使用名为input 的变量,因为这是标准函数的名称。
  • @EitanT 虽然该问题的解决方案应该适用于此处,但这个问题更具体。因此,此处可能会采用对链接问题不可行的解决方案的“捷径”。
  • @DennisJaheruddin 那么它可能是Using a colon for indexing in matrices of unknown dimensions 的副本。我认为大多数新问题都被回收了...... :)

标签: arrays matlab multidimensional-array


【解决方案1】:

这有点小技巧,但你可以这样做:

data = rand(2,2,3);

eval(['data(' repmat(':,',1,ndims(data)-1) '1)'])

这将给出(取决于随机数):

ans =

      0.19255      0.56236
      0.62524      0.90487

【讨论】:

  • 很好看。让我们清理eval 的图像。这很hackish但很有用
  • 不需要eval; MATLAB 的默认 subsref 允许索引的字符串参数,前提是这些字符串是 ':';看我的回答。不过,+1 :)
【解决方案2】:

我认为这样做:

a = rand(2,2,2,3)

s = size(a)
r = reshape(a, [], s(end))
reshape(r(:,1), s(1:end-1)) %// reshape(r(:,2), s(1:end-1)) gives you a(:,:,:,...,2) etc...

我以 Dennis 的(正确)答案为基准,它给出了相同的结果,但不需要 eval,如果可能,这总是值得避免的。

【讨论】:

    【解决方案3】:

    您可以使用shiftdim 将最后一个维度带到第一个维度并索引该维度并将其重新整形

    x = rand(2,3,4,5,6);
    
    sz = size(x);
    A = shiftdim(x, numel(sz)-1);
    B = reshape(A(1,:), sz(1:end-1));
    

    >> isequal(B, x(:,:,:,:,1))
    ans =
         1
    

    或者您也可以使用subsref 对其进行索引:

    B = subsref(x, substruct('()', [num2cell(repmat(':', 1, ndims(x)-1)) 1]))
    

    【讨论】:

    • +1,但最后一步有点尴尬……看我的回答。
    【解决方案4】:

    好问题!

    另一种可能性是在块中使用线性索引,然后重新整形:

    x = rand(2,3,4,5); % example data
    n = 2; % we want x(:,:,...,:,n)
    
    siz = size(x);
    b = numel(x)/siz(end); % block size
    result = reshape(x(b*(n-1)+1:b*n),siz(1:end-1));
    

    这似乎是我电脑中最快的方法(但请自己尝试;这可能取决于 Matlab 版本和系统)

    【讨论】:

    • +1 这几乎是完全我输入的内容。正是这样的问题让我想继续关注 SO,但唉,我不在了。 :(
    • @chappjc 我知道你会喜欢这个问题:-D
    【解决方案5】:

    您应该利用数组的索引可以是包含':'的字符串这一事实:

    >> data = rand(2, 2, 2, 5);
    >> otherdims = repmat({':'},1,ndims(data)-1);
    >> data(otherdims{:}, 1)
    ans(:,:,1) =
        7.819319665880019e-001    2.940663337586285e-001
        1.006063223624215e-001    2.373730197055792e-001
    ans(:,:,2) =
        5.308722570279284e-001    4.053154198805913e-001
        9.149873133941222e-002    1.048462471157565e-001
    

    详情请见the documentation on subsref

    【讨论】:

    • 很好,我一开始就是这样,但是没找到otherdims{:}这一步!
    • 你可以使用字符串吗?哇。 +1
    【解决方案6】:

    以防 GNU Octave 读者到达这里。

    @Rody Oldenhuis 的答案可以用 Octave 写成单行:

    > data = reshape(1:8, 2, 2, 2);
    > data({':'}(ones(1,ndims(data)-1)){:}, 1)
    ans =
    
       1   3
       2   4
    

    这里:

    {':'}(ones(1,ndims(data)-1)){:}
    

    意思是:

    tmp = {':'};
    tmp = tmp(ones(1,ndims(data)-1));
    tmp{:}
    

    当然,repmat({':'},1,ndims(data)-1){:} 也可以。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-24
      • 2020-07-20
      • 2015-08-14
      • 2011-06-24
      • 2016-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多