3 回答
TA贡献1993条经验 获得超5个赞
是的 您可以使用取消引用的单元格数组和“逗号分隔的列表”之间的等价关系,也可以使用char':'作为索引来动态构造A(:, :, :, i, :, ...)任意维度的调用这一事实。
function out = slice(A, ix, dim)
subses = repmat({':'}, [1 ndims(A)]);
subses{dim} = ix;
out = A(subses{:});
这将完全概括化A(:, :, i, :, ...),除了将这些字符串打乱以进行设置之外,还将执行与原始静态表达式完全相同的“切片”索引操作。
或者,如果您愿意,可以只将sprintf其构造A(:, :, i, :, ...)为字符串,然后调用eval()它。但我想尽可能避免eval。
请注意,您最初的实现使用的是快速操作,并且应该执行得很好,大约和这个操作一样快。我之所以发布此内容,是因为我认为它非常易读,确实可以回答您最初提出的问题,并且可以应用于其他有用的内容。
分配给切片
您还可以使用与单元格相同的下标作为左值将其分配给数组的切片。但是,您不能直接重用slice函数,因为它返回数组的提取子集,而不是左值引用。因此,您可以创建一个非常相似的函数来执行分配。
function A = slice_assign(A, ix, dim, B)
%SLICE_ASSIGN Assign new values to a "slice" of A
subses = repmat({':'}, [1 ndims(A)]);
subses{dim} = ix;
A(subses{:}) = B;
在实践中,您可能还需要一个仅返回单元格数组中计算出的索引的函数,因此您可以随身携带这些索引,并重复使用它们进行赋值和引用。
function out = slice_subs(A, ix, dim)
subses = repmat({':'}, [1 ndims(A)]);
subses{dim} = ix;
out = subses;
TA贡献2037条经验 获得超6个赞
您可以尝试permute,并setdiff以该维度移动到一贯立场:
function out = hslice(ndarray, d, i)
subdims = setdiff(1:ndims(ndarray),d);
sz = size(ndarray);
outsz = sz(subdims);
order = [d subdims];
ndarray = permute(ndarray,order);
out = reshape(ndarray(i,:),outsz);
end
例如:
d = 3; i = 2;
nd = randi(23,3,3,3,2);
out = hslice(nd,d,i); % out = squeeze(nd(:,:,i,:)) for d=3
但是,在切片之前,数据将被重写,而不是与问题中的代码一起被重写。因此,我实际上会选择OP!
TA贡献1942条经验 获得超3个赞
如果您要重写subsref
,则可以为普通类不支持的索引类型定义行为。例如,您可以{}
支持任意字符串输入,而不仅限于':',也可以.
采用数字作为参数。我用了一段时间,使它{}
成为内存关系类的RESTRICT操作,并.
成为支持按名称或位置索引列的PROJECT。例如selection = r{''WHERE trade_date > today & price < 14''};
。
添加回答
举报