在MATLAB中,假设我有一组正方形矩阵,比如a,trace(a)=0,如下所示:
例如,
A = [0 1 2; 3 0 4; 5 6 0]
我如何去除零,然后垂直折叠矩阵,使其如下:
A_reduced = [1 2; 3 4; 5 6]
更普遍地说,如果零可以出现在列中的任何位置(即,不一定出现在长对角线上),该怎么办?当然,假设所有列的零总数是相同的。
矩阵可能相当大(尺寸为数百x数百)。因此,一种有效的方式将受到赞赏。
-
垂直压缩矩阵(假设每列都有相同数量的零):
A_reduced_v = reshape(nonzeros(A), nnz(A(:,1)), []);
-
要水平压缩矩阵(假设每一行都有相同数量的零):
A_reduced_h = reshape(nonzeros(A.'), nnz(A(1,:)), []).';
案例#1
假设A
在所有行中有相等数量的零,您可以使用此-水平压缩它(即每行)
At = A' %//'# transpose input array
out = reshape(At(At~=0),size(A,2)-sum(A(1,:)==0),[]).' %//'# final output
示例代码运行-
>> A
A =
0 3 0 2
3 0 0 1
7 0 6 0
1 0 6 0
0 16 0 9
>> out
out =
3 2
3 1
7 6
1 6
16 9
案例#2
如果A
在所有列中有相同数量的零,则可以使用类似的东西垂直压缩它(即每列)
out = reshape(A(A~=0),size(A,1)-sum(A(:,1)==0),[]) %//'# final output
示例代码运行-
>> A
A =
0 3 7 1 0
3 0 0 0 16
0 0 6 6 0
2 1 0 0 9
>> out
out =
3 3 7 1 16
2 1 6 6 9
这似乎很有效,很难通过转座来获得正确的行为:
>> B = A';
>> C = B(:);
>> reshape(C(~C==0), size(A) - [1, 0])'
ans =
1 2
3 4
5 6
由于零总是在主对角线上,您可以执行以下操作:
l = tril(A, -1);
u = triu(A, 1);
out = l(:, 1:end-1) + u(:, 2:end)
一种正确且非常简单的方法可以实现您想要的功能:
A = [0 1 2; 3 0 4; 5 6 0]
A =
0 1 2
3 0 4
5 6 0
A = sort((A(find(A))))
A =
1
2
3
4
5
6
A = reshape(A, 2, 3)
A =
1 3 5
2 4 6
我提出了与E先生几乎相同的解决方案,但使用了另一个整形命令。这种解决方案更通用,因为它使用A
中的行数来创建最终矩阵,而不是计算零的数量或假设零的固定数量。。
B = A.';
B = B(:);
C = reshape(B(B~=0),[],size(A,1)).'