Matlab数组的动态切片
Dynamic slicing of Matlab array
我有一个 n 维数组 A 并想对其进行动态切片,即给定一个数组维数列表,如 [2 4] 和一个值列表,如 [6 8],我想要
B = A(:,6,:,8,:,:,:,:,...)
列表长度未知。使用 eval 可以,但不是一种选择。这个问题是 previous post 在没有 for 循环的情况下对多个索引和维度的概括。
您仍然可以使用 previous post I linked to (which I originally flagged as a duplicate) to answer your question。这个原来的 post 只在一个维度上切片。我最初将其标记为重复并将其关闭,因为您需要做的就是替换原始 post 接受的答案中的一行代码来实现您想要的。但是,因为它不是那么明显,我决定重新打开问题并为您回答问题。
参考前面的 post,这是 Andrew Janke(在链接 post 上接受答案的人)所做的(非常聪明,我可能会补充):
function out = slice(A, ix, dim)
subses = repmat({':'}, [1 ndims(A)]);
subses{dim} = ix;
out = A(subses{:});
给定一个矩阵 A
、一个索引号 ix
和您要访问的维度 dim
,上述函数等效地执行:
out = A(:, :, ..., ix, :, :,...:);
^ ^ ^ ^
dimensions --> 1 2 dim dim+1
您可以在 dim
中访问您想要的维度,并放置您想要用于切分该维度的值。因此,您可以这样称呼它:
out = slice(A, ix, dim);
该函数的工作原理是 subses
将生成一个 ':'
字符串元胞数组(最终将转换为“:”运算符),其长度与维度总数一样长A
个。接下来,您将访问 dim
处的元素,它对应于您想要的维度,并将其替换为 ix
。然后,您将展开此元胞数组,以便我们以您在上述等效语句中看到的方式访问 A
。
Who would have thought that you can use strings to index into an array!?
现在,要概括这一点,您所要做的就是进行一个小但非常关键的更改。 ix
现在将是索引的 向量,而 dim
将是您要访问的维度的 向量。因此,它看起来像这样:
function out = slice(A, ix, dim)
subses = repmat({':'}, [1 ndims(A)]);
subses(dim) = num2cell(ix);
out = A(subses{:});
我们在这里看到的唯一区别是代码的第二行。我们必须使用 num2cell
以便您可以将每个元素转换为元胞数组,然后我们切入此元胞数组以将 :
运算符替换为您想要的维度。请注意,我们使用的是 ()
大括号和 而不是 {}
大括号。 ()
大括号用于对元胞数组进行切片,而 {}
用于访问元胞数组内容。因为我们要将多个单元格分配给 subses
,所以需要 ()
。然后,我们相应地在 A
中执行切片。
因此,考虑到您的问题并进行上述修改,您可以:
out = slice(A, [6 8], [2 4]);
请注意 ix
和 dim
必须 包含相同数量的元素并且它们 必须 1D。此外,ix
和 dim
应该是合理的输入(即不是浮点数和负数)。我不做这个错误检查,因为我假设你知道你在做什么,而且你足够聪明,知道如何正确使用它。
祝你好运!
我有一个 n 维数组 A 并想对其进行动态切片,即给定一个数组维数列表,如 [2 4] 和一个值列表,如 [6 8],我想要
B = A(:,6,:,8,:,:,:,:,...)
列表长度未知。使用 eval 可以,但不是一种选择。这个问题是 previous post 在没有 for 循环的情况下对多个索引和维度的概括。
您仍然可以使用 previous post I linked to (which I originally flagged as a duplicate) to answer your question。这个原来的 post 只在一个维度上切片。我最初将其标记为重复并将其关闭,因为您需要做的就是替换原始 post 接受的答案中的一行代码来实现您想要的。但是,因为它不是那么明显,我决定重新打开问题并为您回答问题。
参考前面的 post,这是 Andrew Janke(在链接 post 上接受答案的人)所做的(非常聪明,我可能会补充):
function out = slice(A, ix, dim)
subses = repmat({':'}, [1 ndims(A)]);
subses{dim} = ix;
out = A(subses{:});
给定一个矩阵 A
、一个索引号 ix
和您要访问的维度 dim
,上述函数等效地执行:
out = A(:, :, ..., ix, :, :,...:);
^ ^ ^ ^
dimensions --> 1 2 dim dim+1
您可以在 dim
中访问您想要的维度,并放置您想要用于切分该维度的值。因此,您可以这样称呼它:
out = slice(A, ix, dim);
该函数的工作原理是 subses
将生成一个 ':'
字符串元胞数组(最终将转换为“:”运算符),其长度与维度总数一样长A
个。接下来,您将访问 dim
处的元素,它对应于您想要的维度,并将其替换为 ix
。然后,您将展开此元胞数组,以便我们以您在上述等效语句中看到的方式访问 A
。
Who would have thought that you can use strings to index into an array!?
现在,要概括这一点,您所要做的就是进行一个小但非常关键的更改。 ix
现在将是索引的 向量,而 dim
将是您要访问的维度的 向量。因此,它看起来像这样:
function out = slice(A, ix, dim)
subses = repmat({':'}, [1 ndims(A)]);
subses(dim) = num2cell(ix);
out = A(subses{:});
我们在这里看到的唯一区别是代码的第二行。我们必须使用 num2cell
以便您可以将每个元素转换为元胞数组,然后我们切入此元胞数组以将 :
运算符替换为您想要的维度。请注意,我们使用的是 ()
大括号和 而不是 {}
大括号。 ()
大括号用于对元胞数组进行切片,而 {}
用于访问元胞数组内容。因为我们要将多个单元格分配给 subses
,所以需要 ()
。然后,我们相应地在 A
中执行切片。
因此,考虑到您的问题并进行上述修改,您可以:
out = slice(A, [6 8], [2 4]);
请注意 ix
和 dim
必须 包含相同数量的元素并且它们 必须 1D。此外,ix
和 dim
应该是合理的输入(即不是浮点数和负数)。我不做这个错误检查,因为我假设你知道你在做什么,而且你足够聪明,知道如何正确使用它。
祝你好运!