【问题标题】:Matlab - Accessing a part of a multidimensional arrayMatlab - 访问多维数组的一部分
【发布时间】:2017-12-25 04:00:42
【问题描述】:

我正在尝试访问 Matlab 中多维数组的一部分 - 可以这样做:X(2:3, 1:20, 5, 4:7) 但是,元素的数量和范围都不是固定的,所以我想提供数组中的索引 - 对于上面的例子,它们是

ind1 = [2 1 5 4];
ind2 = [3 20 5 7];

对于固定数量的维度,这不是问题(X(ind1(1):ind2(1),...),但由于它们不是我不确定如何在 Matlab 中实现这一点。有没有办法?或者我应该以不同的方式处理这个问题?

【问题讨论】:

  • 我有点困惑。您是说尺寸可以从 3D 变为 5D 等?你怎么知道你想要哪些索引?
  • 尺寸不变:如果 u 是 5x7x8x9 数组和 v=u(2:3,6:7,6:6,3:9),那么 v 仍然是 4D - 但是 v(1,1,1,1)=u(2,6,6,3)。访问不是问题,给数组参数是。
  • 我仍在尝试找出您的问题/问题。你想让 v(1,1,1,1) 变成 v(2,6,6,3) 吗?或者您只是想要一种更好的方式来访问 X(ind1(1):ind2(1)...) 。或者您不想手动输入 ind1 = ... 和 ind2 = ... ?
  • 基本上你是一个未知维度的 4D 矩阵/张量,你想根据索引 ind1ind2 提取 4D 子矩阵/张量?那么为什么v = X(ind1(1):ind2(1), ind1(2):ind2(2), ind1(3):ind2(3), ind1(4):ind2(4)); 不能像您一直使用的 4D 一样工作呢?
  • @mpaskov - 我并不总是 4 维的;因此我不能将它“硬编码”为 X(ind1(1):ind2(1), ... ind1(4):ind2(4)) 因为我不知道我有多少参数。

标签: arrays matlab tensor


【解决方案1】:

使用comma separated lists,您可以使其更加快速和友好:

% some test data
ind1 = [2 1 5 4];
ind2 = [3 20 5 7];
X = randi(99,20,20,20,20);

% get all subscripts in column format
vecs = arrayfun(@colon,ind1,ind2,'un',0);
% extract the values
result = X(vecs{:});

【讨论】:

  • 我在上面评论了关于 subs 矩阵大小的问题 - 虽然这个解决方案非常适合小情况,但您知道不保存每个索引的方法吗?
  • @Jabor 查看我的编辑以获得更简单快捷的版本。
【解决方案2】:

可能有更优雅的方法,但这是一个难题,所以这里有一个解决方案:

% some test data
ind1 = [2 1 5 4];
ind2 = [3 20 5 7];
X = randi(99,20,20,20,20);

% get all subscripts in column format
vecs = arrayfun(@colon,ind1,ind2,'Uniformoutput',false);
subs = combvec(vecs{:}).';
% manual sub2ind for a matrix where each row contains one subscript
sizeX = size(X);
idx = cumprod([1 sizeX(1:end-1)])*(subs - [zeros(size(subs,1),1) ones(size(subs,1),size(subs,2)-1)]).';
% reshape
result = reshape(X(idx),ind2-ind1+1);

基于Indexing of unknown dimensional matrix中 Gnovices 答案的索引转换下标

【讨论】:

  • 这是我第一次在 Matlab 中工作,但我想我理解你的方法;非常感谢。我希望我没有要求太多,但是查看它将使用的 subs 矩阵(对于 d 维度和最大为 n 的模式大小;在您的示例中为 d=4 和 n=20)n^d 个条目。这是我的用例中的一个问题,因为成千上万的大小并不罕见。张量本身以一种聪明的方式保存,所以没关系,但这个矩阵将是可笑的巨大。有没有办法规避它的使用?
  • 嗯,我不知道有什么办法。但是如果我没记错的话,subs 矩阵的大小应该只有 d x prod(ind2-ind1+1)?所以它只会随着 ind1 的长度和要提取的元素数量线性增加。
  • 哦,你当然是对的。遗憾的是,ind1 = [1 1 1 1 1 1 1]; ind2 = [15 15 15 15 15 15 15]; 恰好是 8GB
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多