我有一个如下所示的矩阵-
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高手帮帮我。
我有一个如下所示的矩阵-
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高手帮帮我。
你去吧。整个矩阵,没有循环,甚至适用于非连续的零:
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.
一个更通用的例子:
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
有很多方法可以做到这一点。一种快速的方法可以很容易地像这样:
a = [1 2 3 4 0 5 7 0];
idx=(find(a==0));
idx =
5 8
b=a; % save a new copy of the vector
b(idx)=[]; % remove zero elements
b =
1 2 3 4 5 7
c=[b zeros(size(idx))]
c =
1 2 3 4 5 7 0 0
您也可以修改此代码。
如果你的零总是在一起,你可以使用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
试试这个(只是一个快速的黑客):
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 标识符的 MATLAB 版本进行了优化。
@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).'
我也问过这个问题,并在这里得到了一个超级优雅的答案(以上答案都不相同): Optimize deleted matrixleading zeros in MATLAB