【发布时间】:2014-06-25 12:51:29
【问题描述】:
您好,我有以下矩阵:
A= 1 2 3; 0 4 0; 1 0 9
我希望矩阵 A 为:
A= 1 2 3; 1 4 9
PS - 分号代表每列的结束和新列的开始。
如何在 Matlab 2014a 中做到这一点?有什么帮助吗?
谢谢
【问题讨论】:
-
对于结果列,大小服从任何约束?例如相同的列数等。
标签: matlab
您好,我有以下矩阵:
A= 1 2 3; 0 4 0; 1 0 9
我希望矩阵 A 为:
A= 1 2 3; 1 4 9
PS - 分号代表每列的结束和新列的开始。
如何在 Matlab 2014a 中做到这一点?有什么帮助吗?
谢谢
【问题讨论】:
标签: matlab
您在问题陈述中遇到的问题是您不提前知道“压缩”矩阵的形状 - 特别是,您无法知道非零元素的数量是否是 的倍数原始矩阵的行或列。
正如所指出的,有一个简单的函数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, :);
【讨论】:
简单的解决方案:
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
虽然它非常简单,但可能会很慢。您是否需要在非常大/很多的矩阵上执行此操作?
【讨论】:
从您的问题中不清楚您想要什么(如何排列非零值,特别是如果每列中的零数量不同)。也许是这样:
A = reshape(nonzeros(A),[],size(A,2));
【讨论】:
Matlab 的逻辑索引功能非常强大。最好的方法是创建一个逻辑数组:
>> lZeros = A==0
然后使用这个逻辑数组来索引 A 并删除这些零
>> A(lZeros) = []
最后,使用内置的 reshape 命令将数组重新整形为所需的大小
>> A = reshape(A, 2, 3)
【讨论】: