2

私は次のような行列を持っています

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

ベースがあるものA = [ 1 2 3 4];

他にも拠点がありますB = [103 104 105 106];

A の値を M 内の B の値に置き換える必要があります。したがって、新しい M は次のようになります。

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

要素は乱数なので、A と B を 1 対 1 で接続するインデックスを使用する必要があります。もちろん、NO FOR LOOPS :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

new に新しいベースの要素のみMが含まれていることが確実な場合(古いベースと古いベースも同じ)、次の 2 番目の出力を使用できます。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 に答える