多列的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 sub2ind
。 sub2ind
接受行和列位置,输出是列主线性索引,您可以使用它来向量化对矩阵的访问。具体来说,您想要构建一个与 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
假设我有一个 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 sub2ind
。 sub2ind
接受行和列位置,输出是列主线性索引,您可以使用它来向量化对矩阵的访问。具体来说,您想要构建一个与 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