在Matlab中用其他值替换矩阵中的索引

3
假设现在我有一个矩阵。
S = [1 1 1 2 2 2;
     1 1 1 2 2 2;
     2 2 2 2 1 1;
     2 2 2 2 1 1;
     2 2 2 2 1 1]

还有另一个矩阵

A = [1 2;
     2 4]

A中的第一行是S的唯一索引,第二行包含第一行中的值将被替换的值。也就是说,S中所有的“1”都将被替换为2,“2”都将被替换为4。最终我将获得一个矩阵。

SS = [2 2 2 4 4 4;
      2 2 2 4 4 4;
      4 4 4 4 2 2;
      4 4 4 4 2 2;
      4 4 4 4 2 2]

我现在正在做的是:

SS = zeros(size(S));
for i = 1:size(A,2)
    SS(S==index(A(1, i)) = A(2,i);
end

现在,我有一个相当大的矩阵,使用for循环有点慢。是否有更快的方法来做到这一点?


你说过“1”会被替换成“2”,但是 SS 仍然有“1”... 是一个错误吗? - Eitan T
@EitanT 抱歉,已经编辑过了。 - jrenzhile
3个回答

3
使用ismember的第二个输出,给出A矩阵第一行中数值的索引。使用这些索引直接创建矩阵SS
例如(为清晰起见更改了初始值):

S = [5 5 5 3 3 3; 5 5 5 3 3 3; 3 3 3 3 5 5; 3 3 3 3 5 5; 3 3 3 3 5 5]; A = [5 3; 2 4];

>> [~, Locb] = ismember(S,A(1,:))
Locb =

     1     1     1     2     2     2
     1     1     1     2     2     2
     2     2     2     2     1     1
     2     2     2     2     1     1
     2     2     2     2     1     1

>> SS = reshape(A(2,Locb),size(S))
SS =

     2     2     2     4     4     4
     2     2     2     4     4     4
     4     4     4     4     2     2
     4     4     4     4     2     2
     4     4     4     4     2     2

+1 很好。你能否添加一下我的解决方案的执行时间比较(我现在离MATLAB很远)? - Eitan T
@EitanT 它比你的解决方案快大约100倍。但无论如何,还是非常感谢,我真的学到了很多 :) - jrenzhile

1
如果我正确理解了您的问题,我会使用numpy数组而不是标准的Python数组或列表。然后代码变得非常简单,如下所示:
# Import numpy
from numpy import array, zeros, shape
# Create the array S
S = array([[1,1,1,2,2,2],[1,1,1,2,2,2],[2,2,2,2,1,1],[2,2,2,2,1,1],[2,2,2,2,1,1]])
# Create the array A
A = array([[1,2],[2,4]])
# Create the empty array SS
SS = zeros((shape(S)))
# Actual operation needed 
SS[S==A[0,0]]=A[1,0]
SS[S==A[0,1]]=A[1,1]

现在,如果你看到数组SS,它将如下所示:

SS
array([[ 2.,  2.,  2.,  4.,  4.,  4.],
       [ 2.,  2.,  2.,  4.,  4.,  4.],
       [ 4.,  4.,  4.,  4.,  2.,  2.],
       [ 4.,  4.,  4.,  4.,  2.,  2.],
       [ 4.,  4.,  4.,  4.,  2.,  2.]])

之前可能有些混淆,抱歉。我错误地认为这个问题是关于Python的(我的错!)。无论如何,MATLAB的答案非常相似:

SS = zeros(size(S))
SS(S==A(1,1))=A(2,1)
SS(S==A(1,2))=A(2,2)

谢谢,但我的标签是“matlab”,对于误解我感到抱歉。 - jrenzhile
非常抱歉。实际上,我自己也在寻找有关Python/Mayavi的东西,当我偶然发现这个问题时。由于我可能知道答案,所以我没有看标签就跳进了帮助中心。下次我会小心的。谢谢。 - Indranil Sinharoy

1
你可以使用arrayfun一行代码来完成这个操作,就像这样:
SS = arrayfun(@(x)A(2, (A(1, :) == x),  S)

非常感谢,但是如果矩阵S中的索引不连续,比如说"S"中的"2"是"3",那该怎么办呢?如果出现这种情况,我认为我只能更改矩阵A以添加一些条目,以便使用您建议的代码。还有其他方法吗? - jrenzhile
我的意思是,对于一个新的矩阵S,它的索引为1或3。而A包含了1->2、3->6等信息。在这种情况下,我无法使用您建议的代码,因为在您的代码中,n不仅代表A的列数,还代表S的实际值。因此,您的任何建议都无法工作,因为我们会遇到超出索引的错误。 - jrenzhile
哦,我明白了。请尝试我的修订答案,看看它是否更快。 - Eitan T
很遗憾,arrayfun 通常不会比基本的 for 循环更快。它值得测试 - 我想看到速度测试的结果 - 但我对这种方法加速并不抱有希望。 - tmpearce

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接