2

以下のようなマトリックスが1つあります-

A=[1 1 1 1 1;
   0 1 1 1 2;
   0 0 1 1 3]

しかし、すべてを行の最後に配置したい0ので、A は次のようになります。

A=[1 1 1 1 1;
   1 1 1 2 0;
   1 1 3 0 0] 

これどうやってするの?Matlabの専門家が私を助けてください。

4

7 に答える 7

4

ほらね。連続していないゼロに対しても、ループなしの行列全体が機能します。

A = [1 1 1 1 1; 0 1 1 1 2; 0 0 1 1 3];

At = A.'; %// It's easier to work with the transpose
[~, rows] = sort(At~=0,'descend'); %// This is the important part.
%// It sends the zeros to the end of each column
cols = repmat(1:size(At,2),size(At,1),1);
ind = sub2ind(size(At),rows(:),cols(:));
sol = repmat(NaN,size(At,1),size(At,2));
sol(:) = At(ind);
sol = sol.'; %'// undo transpose

~いつものように、関数リターンのシンボルをサポートしていない Matlab バージョンでは~、ダミー変数で変更します。たとえば、次のようになります。

[nada, rows] = sort(At~=0,'descend'); %// This is the important part.
于 2013-08-09T16:52:15.397 に答える
4

より一般的な例:

A = [1 3 0 1 1;
     0 1 1 1 2;
     0 0 1 1 3]

% Sort columns directly
[~,srtcol] = sort(A == 0,2);
% Sorted positions 
sz  = size(A);
pos = bsxfun(@plus, (srtcol-1)*sz(1), (1:sz(1))'); % or use sub2ind

結果

B = A(pos)
B =
     1     3     1     1     0
     1     1     1     2     0
     1     1     3     0     0
于 2013-08-09T21:29:13.217 に答える
1

ゼロが常に一緒である場合は、circshiftコマンドを使用できます。これは、配列内の値を指定された数だけシフトし、端からはみ出した値を反対側にラップします。の各行に対して個別にこれを行う必要があるように見えるAので、上記の例では次のことを試すことができます。

A(2,:) = circshift(A(2,:), [1 -1]);    % shift the second row one to the left with wrapping
A(3,:) = circshift(A(3,:), [1 -2]);    % shift the third row two to the left with wrapping

一般に、ゼロが の行の先頭に常にある場合はA、次のようなことを試すことができます。

for ii = 1:size(A,1)                              % iterate over rows in A
    numShift = numel(find(A(ii,:) == 0));         % assuming zeros at the front of the row, this is how many times we have to shift the row.
    A(ii,:) = circshift(A(ii,:), [1 -numShift]);  % shift it
end
于 2013-08-09T16:38:08.320 に答える
1

@LuisMendoの答えはその優雅さに刺激的ですが、私はそれを機能させることができませんでした(おそらくmatlabバージョンのもの)。以下は(彼の答えに基づいて)私にとってはうまくいきました:

Aaux = fliplr(reshape([1:numel(A)],size(A)));
Aaux(find(A==0))=0;
[Asort iso]=sort(Aaux.',1,'descend');
iso = iso + repmat([0:size(A,1)-1]*size(A,2),size(A,2),1);
A=A.';
A(iso).'
于 2013-08-10T00:18:02.223 に答える
1

これを試してください(簡単なハックです):

for row_k = 1:size(A, 1)
   [A_sorted, A_sortmap] = sort(A(row_k, :) == 0, 'ascend');

   % update row in A:    
   A(row_k, :) = A(row_k, A_sortmap);
end

~ガベージ lhs-identifier としてサポートされていない MATLAB のバージョン用に最適化されました。

于 2013-08-09T16:39:42.510 に答える
0

私もこの質問をして、非常にエレガントな答えを得ました (上記の答えは同じではありません) ここ: MATLAB で行列の先行ゼロを削除する最適化

于 2013-12-25T20:55:39.820 に答える