简体   繁体   English

3D矩阵:如何在MATLAB中将(行,列)对与3维通配符一起使用?

[英]3d matrix: how to use (row, column) pairs with 3rd dimension wildcard in MATLAB?

I have a 3 dimensional matrix, and a list of (row, column) pairs. 我有一个3维矩阵,以及(行,列)对的列表。 I would like to extract the 2 dimensional matrix that corresponds to the elements in those positions, projected through the depth of the matrix. 我想提取二维矩阵,该二维矩阵对应于那些位置的元素,并通过矩阵的深度进行投影。 For instance, suppose, 例如,假设

>> a = rand(4, 3, 2)
a(:,:,1) =
    0.5234    0.7057    0.0282
    0.6173    0.2980    0.9041
    0.7337    0.9380    0.9639
    0.0591    0.8765    0.1693
a(:,:,2) =
    0.8803    0.2094    0.5841
    0.7151    0.9174    0.6203
    0.7914    0.7674    0.6194
    0.2009    0.2542    0.3600
>> rows = [1 4 2 1];
>> cols = [1 2 1 3];

What I'd like to get is, 我想得到的是

0.5234    0.8765    0.6173    0.0282
0.8803    0.2542    0.7151    0.5841

maybe with some permutation of dimensions. 也许有一些尺寸的变化。 Also, although this example has the wildcard in the last dimension, I also have cases where it's in the first or second. 另外,尽管此示例在最后一个维度中使用通配符,但在某些情况下,我也使用了通配符。

I naively tried a(rows, cols, :) and got a 3d matrix where the diagonal plane is what I want. 我天真地尝试a(rows, cols, :)并得到了一个3d矩阵,其中对角线就是我想要的。 I also found sub2ind , which will extract the desired elements from the a(:,:,1) plane. 我还发现sub2ind ,它将从a(:,:,1)平面中提取所需的元素。 I could work with one of these to get to what I want, but I'm wondering is there a more canonical, elegant, or efficient method that I'm missing? 我可以使用其中之一来实现所需的功能,但我想知道是否还有我遗漏的更规范,更优雅或更有效的方法?

Update 更新

This was the solution I used, based on the answer posted below, 根据下面发布的答案,这就是我使用的解决方案,

sz = size(a);
subs = [repmat(rows, [1, sz(3)]);
     repmat(cols, [1, sz(3)]);
     repelem([1:sz(3)], length(rows))];
result = a(sub2ind(sz, subs(1,:), subs(2,:), subs(3,:)));

sub2ind is pretty much what you have to use here to convert your subscripts into linear indices (apart from manually computing the linear indices yourself). sub2ind几乎是您在这里需要使用的将下标转换为线性索引的方法(除了您自己手动计算线性索引之外)。 You can do something like the following which will convert the rows and cols to a linear index (in a 2D slice) and then it adds an offset (equal to the number of elements in a 2D slice) to these indices to sample all elements in the third dimension. 你可以做这样的事情,这将在转换以下rowscols的线性指标(在2D切片),然后它添加一个偏移量(等于一个二维切片元素的数量),以这些指标来样元素第三维。

sz = size(a);
inds = sub2ind(sz(1:2), rows, cols);
inds = bsxfun(@plus, inds, (0:(sz(3)-1)).' * prod(sz(1:2)));
result = a(inds);

And to actually compute the linear indices yourself 并自己实际计算线性指数

inds = (cols - 1) * sz(1) + rows;
inds = bsxfun(@plus, inds, (0:(sz(3) - 1)).' * prod(sz(1:2)));
result = a(inds);

Another option would be to permute your initial matrix to bring the third dimension to the first dimension, reshape it to a 2D matrix, and then use the linear index as the second subscript 另一种选择是置换您的初始矩阵,以将第三维变为第一维,将其重塑为二维矩阵,然后将线性索引用作第二个下标

% Create a new temporary matrix
anew = reshape(permute(a, [3, 1, 2]), size(a, 3), []);

% Grab all rows (the 3rd dimension) and compute the columns to grab
result = anew(:, (cols - 1) * size(a, 1) + rows);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM