2

2D (5x5) 行列があるとします。

test =  

39   13   90    5   71  
60   78   38    4   11  
87   92   46   45   35  
40   96   61   17    1  
90   50   46   89   63  

そして 2 番目の 2D (5x2) 行列:

tidx =

1   3  
2   4  
2   3  
2   4  
4   5  

そして、次の出力が得られるように、tidx をテストへの Idex として使用したいと考えています。

out =

39   90  
78    4  
92   46      
96   17  
89   63  

これを行う1つの方法は、forループを使用することです...

for i=1:size(test,1)     
   out(i,:) = test(i,tidx(i,:)); 
end

質問:

これをベクトル化して、for ループなしで同じ出力が生成されるようにする方法はありますか?

4

1 に答える 1

2

1 つの方法を次に示します。

test(repmat([1:rows(test)]',1,columns(tidx)) + (tidx-1)*rows(test))

あなたが説明するのはインデックスの問題です。行列をすべて 1 次元に配置すると、次のようになります。

test(:) =
39
60
87
40
90
13
78
92
96
50
90
38
46
61
46
 5
 4
45
17
89
71
11
35
 1
63

これは、単一の数値を使用して索引付けできます。tidx を正しい形式に変換する方法を理解する方法は次のとおりです。

まず、上記の参照を使用して、次のインデックス番号を見つけます。

outinx =
 1 11
 7 17
 8 13
 9 19
20 25

それから私はパターンを理解しようとし始めます。この計算から手がかりが得られます。

(tidx-1)*rows(test) =
0   10
5   15
5   10
5   15
15   20

これにより、インデックス カウントが test の正しい列に移動します。今、私は正しい行が必要です。

outinx-(tidx-1)*rows(test) =
1   1
2   2
3   3
4   4
5   5

このパターンは for ループによって作成されます。そのマトリックスを次のように作成しました。

[1:rows(test)]' * ones(1,columns(tidx))

*編集: これは組み込み関数で同じことを行います。

repmat([1:rows(test)]',1,columns(tidx))

次に、2 つを足し合わせて、テスト用のインデックスとして使用します。

于 2012-09-17T20:33:29.627 に答える