多列的matlab矩阵索引

matlab matrix indexing of multiple columns

假设我有一个 IxJ 值矩阵,

V= [1,4;2,5;3,6];

和索引的 IxR 矩阵 X,

X = [1 2 1 ; 1 2 2 ; 2 1 2];

我想得到一个矩阵 Vx,它是 IxR,这样对于每一行 i,我想读取 R 乘以 V 的(可能)不同列,这些列由 X 中每个对应列中的数字给出。

Vx(i,r) = V(i,X(i,r)).

例如在这种情况下它将是

Vx = [1,4,1;2,5,5;6,3,6];

非常感谢任何有助于快速完成此操作(没有任何循环)的人!

所以你想要实现的是使用矢量化来实现速度。这是 MATLAB 的主要优势之一。您想要的是一个矩阵(以下代码中的index),其元素是线性索引,用于从源矩阵中挑选出值(在您的情况下为V)。前两行代码做的事情与 sub2ind 完全相同,将下标转换为线性索引。我这样编码,索引转换的逻辑就很清楚了。

[m,n] = ndgrid(1:size(X,1),1:size(X,2));
index = m + (X-1)*size(X,1);
Vx = V(index);

另一种方法是使用 repmat combined with sub2indsub2ind 接受行和列位置,输出是列主线性索引,您可以使用它来向量化对矩阵的访问。具体来说,您想要构建一个与 X 大小相同的行索引和列索引的二维矩阵,其中列索引完全指定为 X 但行索引对于每一行都是相同的我们关心的。具体来说,该矩阵的第一行全为 1,下一行全为 2,依此类推。要构建该行矩阵,首先生成一个列向量,该列向量从 1 到行数与 X 一样多,并且将此复制到与 X 中一样多的列。使用这个新矩阵和 X,使用 sub2ind 生成列主线性索引,最终索引 V 以生成矩阵 Vx:

subs = repmat((1:size(X,1)).', [1 size(X,2)]); %'
ind = sub2ind(size(X), subs, X);
Vx = V(ind);

您可以使用 bsxfun 来获得有效的解决方案 -

N = size(V,1)
Vx = V(bsxfun(@plus,[1:N]',(X-1)*N))

样本运行-

>> V
V =
     1     4
     2     5
     3     6
>> X
X =
     1     2     1
     1     2     2
     2     1     2
>> N = size(V,1);
Vx = V(bsxfun(@plus,[1:N]',(X-1)*N))
Vx =
     1     4     1
     2     5     5
     6     3     6