您好我有以下矩阵:
A = 1 2 3; 0 4 0; 1 0 9
我希望矩阵A为:
A = 1 2 3; 1 4 9
PS - 分号表示每列的结尾,新列开始。
我如何在Matlab 2014a中做到这一点?有什么帮助吗?
由于
答案 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)