在没有for循环的情况下更改矩阵的多个元素(已知坐标)

时间:2012-09-06 06:34:17

标签: matlab vectorization

我有一个矩阵说

Z = [1 2 3;
     4 5 6;
     7 8 9]

我必须将其值(例如位置(2,2)和(3,1))更改为某个指定值。我有两个矩阵rowNoscolNos,其中包含以下这些位置:

rowNos = [2, 3]
colNos = [2, 1]

假设我想将这些位置的元素值更改为0。

如果不使用for循环,我怎么能这样做?

3 个答案:

答案 0 :(得分:5)

使用sub2ind,它会将您的子索引转换为线性索引,这是一个指向矩阵中一个确切位置的数字(more info)。

Z = [ 1 2 3 ; 4 5 6 ; 7 8 9];
rowNos = [2, 3];
colNos = [2, 1];

lin_idcs = sub2ind(size(Z), rowNos, colNos)

如果要对特定行和列(更高维度的元素)上的所有元素进行操作,您还可以使用线性索引来处理它们。计算它们只会变得有点棘手:

Z = reshape(1:4*4*3,[4 4 3]);
rowNos = [2, 3];
colNos = [2, 1];

siz = size(Z);
lin_idcs = sub2ind(siz, rowNos, colNos,ones(size(rowNos))); % just the first element of the remaining dimensions
lin_idcs_all = bsxfun(@plus,lin_idcs',prod(siz(1:2))*(0:prod(siz(3:end))-1)); % all of them
lin_idcs_all = lin_idcs_all(:);

Z(lin_idcs_all) = 0;

使用sub2ind进行一些实验,并逐步完成我的代码以了解它。

如果它是你想要关闭所有元素的第一个维度会更容易,那么你可以使用冒号运算符:

Z = reshape(1:3*4*4,[3 4 4]);
rowNos = [2, 3];
colNos = [2, 1];

siz = size(Z);
lin_idcs = sub2ind(siz(2:end),rowNos,colNos);
Z(:,lin_idcs) = 0;

答案 1 :(得分:2)

sub2ind与行和列的多个条目一起使用

Z(sub2ind(size(Z), rowNos, colNos))=0

示例

Z = [1 2 3;
    4 5 6;
    7 8 9];

rowNos = [2, 3];
colNos = [2, 1];

Z(sub2ind(size(Z), rowNos, colNos))=0

Z =

     1     2     3
     4     0     6
     0     8     9

答案 2 :(得分:1)

你想这样做

z(rowNos, colNos)

但你不能 - MATLAB做了索引的笛卡尔积。你可以做到这一点

idx=(colNos-1)*size(z, 1)+rowNos;
z(idx)=0

展平z矩阵并通过线性索引访问它,该索引是rowNos和colNos的组合。请记住,MATLAB按列平整矩阵(基于列的矩阵存储)。