我有一个n维数组A,想要动态切片,即给定一个数组维度列表,如[2 4],以及一个值列表,如[6 8],我想要
B = A(:,6,:,8,:,:,:,:,...)
列表长度未知。使用eval会起作用,但不是一种选择。这个问题是previous post到多个索引和维度的概括,没有for循环。
答案 0 :(得分:2)
您仍然可以使用previous post I linked to (which I originally flagged as a duplicate) to answer your question。这个原始帖子只在一个维度上切片。我最初将其标记为重复并关闭它,因为您需要做的就是替换原始帖子中的一行代码,以实现您想要的答案。但是,因为它不是那么明显,我决定重新打开问题并为你回答问题。
参考上一篇文章,这是Andrew Janke(链接帖子中接受答案的人)所做的事情(我可能会非常聪明地添加):
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
。
谁会想到你可以使用字符串索引到数组中??
现在,为了概括这一点,你所要做的就是做一个小但非常关键的改变。 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
应该是明智的输入(即不是浮点和负值)。我没有做错误检查,因为我假设你知道自己在做什么,而且你已经足够聪明,知道如何正确使用它。