2

我有一个矩阵,例如

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谢谢

4

3 回答 3

6

这是给你的单线:

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 加速)循环胜过两者。令人惊讶,不是吗?:)

于 2013-05-29T11:41:10.973 回答
4

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

 >> [~,b] = ismember(M,A);      
 >> M = B(b)
 M =
    103   105   104   106
    105   105   104   103
    104   106   103   105
于 2013-05-29T11:41:25.097 回答
2

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

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。(如果是适当的基础,可能不应该发生)。

于 2013-05-29T11:35:51.373 回答