消除矩阵中的零 - Matlab

时间:2014-06-25 12:51:29

标签: matlab

您好我有以下矩阵:

A = 1 2 3;    0 4 0;    1 0 9

我希望矩阵A为:

A = 1 2 3;    1 4 9

PS - 分号表示每列的结尾,新列开始。

我如何在Matlab 2014a中做到这一点?有什么帮助吗?

由于

4 个答案:

答案 0 :(得分:2)

问题陈述遇到的问题是你提前不知道“挤压”矩阵的形状这一事实 - 特别是,你无法知道非零元素的数量是否是原始矩阵的行或列。

正如所指出的,有一个简单的函数nonzeros,它返回输入的非零元素,按列排序。在你的情况下,

A = [1 2 3;
     0 4 0;
     1 0 9];
B = nonzeros(A)

产生

1
1
2
4
3
9

你想要的是

1 2 3
1 4 9

这恰好是你按列“挤出”零时所得到的。这将与

一起获得(当每列中的零个数相同时)
reshape(B, 2, 3);

我认为最好假设每列中的元素数量可能不一样 - 那么你需要创建一个稀疏数组。这实际上非常简单:

S = sparse(A);

结果对象S是一个稀疏数组 - 也就是说,它只包含非零元素。当许多元素为零时,它非常有效(包括存储和计算):一旦超过1/3的元素非零,它会很快变得更慢/更大。但它具有保持矩阵形状的优点,无论零的分布如何。

更强大的解决方案必须检查每列中非零元素的数量,并确定最终矩阵的形状:

cc = sum(A~=0);

将计算矩阵每列中非零元素的数量。

nmin = min(cc);
nmax = max(cc);

在任何列中找到最小和最大数量的非零元素

[i j s] = find(A); % the i, j coordinates and value of nonzero elements of A
nc = size(A, 2); % number of columns

B = zeros(nmax, nc);
for k = 1:nc
  B(1:cc(k), k) = s(j == k);
end

现在B具有所有非零元素:对于具有较少非零元素的列,末尾将填充零。最后,您可以决定是否要修剪矩阵B - 如果您想要根本没有零,则需要修剪较长列中的某些值。例如:

B = B(1:nmin, :); 

答案 1 :(得分:0)

简单的解决方案:

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

A =

     1     2     3
     0     4     0
     1     0     9

A(A==0) = [];

A =

     1     1     2     4     3     9

reshape(A,2,3)

ans =

     1     2     3
     1     4     9

虽然很简单但可能很慢。你需要在非常大/很多的矩阵上执行这个操作吗?

答案 2 :(得分:0)

根据您的问题,您不清楚您想要什么(如何排列非零值,特别是如果每​​列中的零数不相同)。也许这个:

A = reshape(nonzeros(A),[],size(A,2));

答案 3 :(得分:0)

Matlab的逻辑索引非常强大。最好的方法是创建一个逻辑数组:

>> lZeros = A==0

然后使用此逻辑数组索引到A并删除这些零

>> A(lZeros) = []

最后,使用内置的重塑命令

将数组重新整形为所需的大小
>> A = reshape(A, 2, 3)