【问题标题】:Replacing Matrix Values in MATLAB在 MATLAB 中替换矩阵值
【发布时间】:2013-05-24 15:31:29
【问题描述】:

我有一个矩阵比如

M = [ 1 3 2 4;
      3 3 2 1;
      2 4 1 3]

有一个基础A = [ 1 2 3 4];

我还有另一个基地B = [103 104 105 106];

我需要用 M 中的 B 值替换 A 的值。所以我的新 M 应该是:

M1 = [ 103  105 104 106;
       105  105 104 103;
       104  106 103 105];

元素是随机数,所以我需要在 A 和 B 之间使用索引一对一的连接。 我应该提一下吗?当然没有循环:D 谢谢

【问题讨论】:

    标签: arrays matlab replace


    【解决方案1】:

    如果您的基础是旧基础的简单功能,则它可能是微不足道的:

    M1 = M + 102;
    

    否则这是一种方式:

    M1 = M
    for t = 1:length(A)
        M1(M==A(t)) = B(t)
    end
    

    根据@Rody 的回答,另一种解决方案:

    [idx,b] = ismember(M,A);      
    M(idx) = B(b(idx))
    

    不同的是,如果A 不包含M 的所有元素,这不会中断。 (如果是适当的依据,应该不会发生)。

    【讨论】:

    • 最后一个可能是我自己更喜欢的。
    【解决方案2】:

    这是一个适合你的单行:

    sum(bsxfun(@times, bsxfun(@eq, M, reshape(A,1,1,[])), reshape(B,1,1,[])), 3)
    

    相当快。

    基准测试

    这是基准测试代码:

    %// bsxfun party
    tic
    for k = 1:10000
        M1 = sum(bsxfun(@times,bsxfun(@eq,M,reshape(A,1,1,[])),reshape(B,1,1,[])),3);
    end
    toc
    
    %// Using ismember
    tic
    for k = 1:10000
        [idx,b] = ismember(M,A);      
        M(idx) = B(b(idx));
    end
    toc
    
    %// Using a simple loop
    tic
    for k = 1:10000
        M1 = M;
        for t = 1:length(A)
            M1(M == A(t)) = B(t);
        end
    end
    toc
    

    结果是:

    Elapsed time is 0.030135 seconds.
    Elapsed time is 0.094354 seconds.
    Elapsed time is 0.007410 seconds.
    

    所以这个单线比ismember 的优雅解决方案更快,但简单的(JIT 加速)循环胜过两者。令人惊讶,不是吗? :)

    【讨论】:

      【解决方案3】:

      如果您确定新的M 包含来自新基的 元素(旧的M 和旧的基相同),您可以使用ismember 的第二个输出:

       >> [~,b] = ismember(M,A);      
       >> M = B(b)
       M =
          103   105   104   106
          105   105   104   103
          104   106   103   105
      

      【讨论】:

      • 优雅,但比循环慢:)
      • 我希望想出什么!稍作编辑,因此如果M 的所有元素并非都出现在A 中,它也可以工作
      • @DennisJaheruddin:当我提到的那些条件成立时,允许省略 idx。我认为对于这种情况,省略它们会更优雅,所以如果你不介意,我会回滚。
      • @DennisJaheruddin:啊,我想你编辑了一个旧版本:)
      • @EitanT:令人惊讶?几乎没有,如果你看看edit ismember :)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-06
      • 1970-01-01
      • 2012-11-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多