2

ペアの2D配列から値を取得し、それに加えて行の最後の数値を取得するスマートな方法はありますか?

私のデータ(ファイルに保存されている)は次のようになります。

  0  89  27 100  42  75 8  
  0 100   7  92   5  68 6  
  0  67  49  83 100 100 2  
 35  76  57 100 100  92 5  
 18  68  50  54 100  19 3  

このデータをMatlabにロードした後、常にペアを取得してデータをタプルにグループ化する必要があります。この例では、次のようになります。

[0,89]、[27,100]、[42,75]、[0,100]、... [100,19]

データをペアリングした後(またはその間に)、行の最後の番号をペアに追加する必要があります。前述のデータは次のように変更されます。

[0,89,8]、[27,100,8]、[42,75,8]、[0,100,6]、... [100,19,3]

これを解決するための賢い方法はどのようになりますか?私は個人的にループの広範な使用を嫌い、より良い解決策があると思います。

4

5 に答える 5

2

編集:これでうまくいくはずです。

M=[0  89  27 100  42  75 8  
  0 100   7  92   5  68 6  
  0  67  49  83 100 100 2  
 35  76  57 100 100  92 5  
 18  68  50  54 100  19 3]

X = M(:,1:end-1)
Y = M(:,end)
idxOdd = mod(1:size(X,2),2)==1
Xeven=X(:,~idxOdd)
Xodd=X(:,idxOdd)

Yrep = repmat(Y,1,sum(idxOdd))

[Xodd(:) Xeven(:) Yrep(:)]
于 2012-10-31T16:50:15.963 に答える
2

誰もこれを思い付いていないのは驚くべきことだと思います。

M = [   
  0  89  27 100  42  75 8  
  0 100   7  92   5  68 6  
  0  67  49  83 100 100 2  
 35  76  57 100 100  92 5  
 18  68  50  54 100  19 3  ];


C = arrayfun(...
    @(ii) [M(:,ii:ii+1) M(:,end)], ...
    1:2:size(M,2)-1, 'UniformOuput', false);

最終的に次のセル配列になります。

>> C{1}

ans =

     0    89     8
     0   100     6
     0    67     2
    35    76     5
    18    68     3

>> C{2}

ans =

    27   100     8
     7    92     6
    49    83     2
    57   100     5
    50    54     3

>> C{3}

ans =

    42    75     8
     5    68     6
   100   100     2
   100    92     5
   100    19     3

これで、次のように個々のタプルを参照できます。

C{1}(2,:)   %  [  0   100   6]
C{3}(4,:)   %  [100    92   5]
于 2012-10-31T19:56:20.517 に答える
1

これは、論理インデックスを使用して実行できます。デニスの答えから構築する:

z = M(:,end); %# extract the last column
M = M(:,1:end-1); %# chop off the last column from the rest of your data
xidx = logical(mod(1:size(M,2),2)); %# get a logical index of the odd numbered rows
x = M(:,xidx); %# grab the x values
y = M(:,~xidx); %# grab the y values
z = repmat(z,1,numel(x)/numel(z)); % replicate z to match numel of x and y
x = reshape(x',numel(x),1);    %# reshape the arrays to form the right dimensions
y = reshape(y',numel(y),1);
z = reshape(z',numel(z),1);
output = [x,y,z]; %# format output
于 2012-10-31T17:16:37.360 に答える
1

データを行列Aにグループ化するには、セルタプルの配列を使用cell2matして出力しC、この配列の対応する行の最後の列要素を追加します。

% separate the data pairs
C = mat2cell(A(:,1:end-1), ones(1,size(A,1)), 2*ones(1,3));

% single for-loop to append line_lat_element in cells of same row
for i = 1:size(A,1)
    D(i,:) = cellfun(@(x) [x A(i,end)], {C{i,:}}, 'UniformOutput', false);
end

D{i,j}出力として、セル配列の各エントリにはトリプレットが含まれます[data1 data2 last_element_of_line]

于 2012-10-31T17:28:16.567 に答える
1

forこの場合、謙虚なループを守りたいと思います。

M = [  0  89  27 100  42  75 8  ;
         0 100   7  92   5  68 6  ;
         0  67  49  83 100 100 2  ;
        35  76  57 100 100  92 5  ;
        18  68  50  54 100  19 3 ];

out = zeros((size(M,2)-1)/2*size(M,1),3);
ind = 1;
for row = 1:size(M,1)
    for col = 1:2:(size(M,2)-1)
        out(ind,:) = [M(row,col:col+1) M(row,end)];
        ind = ind+1;
    end
end
out

これは、非ループバージョンよりも記述、理解、および保守が容易であると私は主張します(コードを初めて使用するプログラマー、または同じプログラマーが数週間、数か月、または数年後にコードに戻る場合)。少しトリッキーな部分は、出力行列の適切なサイズを計算することだけoutです。パフォーマンスが問題になる場合は、必ず非ループバージョンを確認してください。しかし、MATLABの最近のバージョンは、以前よりもはるかに高速にforループを実行します。それでは、なぜ時期尚早に最適化するのでしょうか。

rowとに基づく巧妙な計算により、実行中のインデックスを維持する必要をなくすことができますがcol、なぜわざわざするのでしょうか。上記のコードは、プログラマーにとってシンプルで理解しやすいものです。

于 2012-10-31T17:38:06.463 に答える