移除零,然后垂直折叠矩阵



在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)).'

最新更新