2017-01-09 6 views
1

私はoldMatを持っています。これは株価指数のランキングです。列番号はそれぞれのランクを表す。第1の列は最高ランクに等しく、第2の列は2番目に高いランクに等しくなる。 oldMatの整数は個々の株式ティッカーの番号を表します。 3の数字はoldMat(3,2,1)で、第3の株式ティッカーは第3の期間で2番目にランク付けされていることを意味します(行は異なる期間を表します)。ループのない変換行列

今、私はoldMatを次のように変換する必要があります。列番号は個々の株式ティッカーを表します。整数は、個々の株式ティッカーが特定の期間に保持するランクを表します。たとえば、2の数字がnewMat(3,3,1)の場合、3番目の株式ティッカーは3番目の期間で2番目にランク付けされています。

私はその問題を解決するためにfor-loopを使用しましたが、この結果を達成するためのより効率的な方法が存在すると確信しています。ここに私のコード:

% Define oldMat 
oldMat(:,:,1) = ... 
    [NaN, NaN, NaN, NaN, NaN, NaN; ... 
    1, 3, 4, 6, 2, 5; ... 
    6, 3, 4, 1, 2, 5; ... 
    2, 3, 6, 1, 4, 5; ... 
    5, 4, 6, 2, 3, 1; ... 
    5, 1, 2, 3, 6, 4; ... 
    4, 5, 1, 3, 6, 2; ... 
    4, 1, 6, 5, 2, 3]; 
oldMat(:,:,2) = ... 
    [NaN, NaN, NaN, NaN, NaN, NaN; ... 
    NaN, NaN, NaN, NaN, NaN, NaN; ... 
    1, 6, 3, 4, 2, 5; ... 
    6, 3, 2, 1, 4, 5; ... 
    2, 6, 3, 4, 1, 5; ... 
    5, 2, 1, 6, 3, 4; ... 
    5, 1, 3, 6, 2, 4; ... 
    4, 1, 5, 6, 3, 2]; 

% Pre-allocate newMat 
newMat = nan(size(oldMat)); 

% Transform oldMat to newMat 
for runNum = 1 : size(newMat,3) 

    for colNum = 1 : size(newMat,2) 

     for rowNum = 1 : size(newMat,1) 
      if ~isnan(oldMat(rowNum, colNum, runNum)) 
       newMat(rowNum,oldMat(rowNum, colNum, runNum), runNum) = colNum; 
      end 
     end 

    end 

end 

答えて

2

sub2indのように見えます。新しい行列の2番目の次元にアクセスするための線形インデックスのセットを作成し、それらを列番号と等しく設定したいとします。最初にmeshgridで3D座標のグリッドを作成し、oldMat行列を出力の2番目の列のインデックスとして使用し、これを列番号と同じに設定します。 NaNの値をコピーしないか、またはsub2indをコピーしないでください。 isnanを使用すると、これらの値をフィルタリングするのに役立ちます。

% Initialize new matrix 
newMat = nan(size(oldMat)); 

% Generate a grid of coordinates 
[X,Y,Z] = meshgrid(1:size(newMat,2), 1:size(newMat,1), 1:size(newMat,3)); 

% Find elements that are NaN and remove 
mask = isnan(oldMat); 
X(mask) = []; Y(mask) = []; Z(mask) = []; 

% Set the values now 
newMat(sub2ind(size(oldMat), Y, oldMat(~isnan(oldMat)).', Z)) = X; 
関連する問題