我有一个看起来像这样的矢量:
A = [1 7 3 4 0 0 0 0 0 0 1 4 5 3 2 4 0 0 0 0 0 0 0 2 4 3 10 3 5 3 2 1]
我希望矢量看起来像这样:
1 7 3 4
1 4 5 3 2 4
2 4 3 10 3 5 3 2 1
我正在尝试从向量中删除零,并且当存在零时,将之前的数字替换为新列并继续向量的长度。我目前正在使用命令L = A(A~=0)
删除零,但卡在那里。
答案 0 :(得分:1)
如果你想让结果成为矩阵......你不能。如图所示,矩阵不能包含空元素。你能做的最好的是一个单元格数组,其中单元格的每个元素对应于“矩阵”中的一行。
首先,我们可以找到不为零的所有位置:
>> nonZeroIndices = find(A)
nonZeroIndices =
1 2 3 4 11 12 13 14 15 16 24 25 26 27 28 29 30 31 32
很明显,索引的“运行”对应于A
中存在非零的位置。也就是说,某个索引n
和n-1
之间的差异是1.让我们使用diff
来查找描述:
>> diff(nonZeroIndices)
ans = 1 1 1 7 1 1 1 1 1 8 1 1 1 1 1 1 1 1
非一个值对应于运行中出现“中断”的位置。让我们找到那些指数..
>> breakIndices = find(diff(nonZeroIndices) > 1)
breakIndices =
4 10
所以A(nonZeroIndices(1:4))
,A(nonZeroIndices(5:10))
和A(nonZeroIndices(11:end))
对应于我们想要的3“行”。请注意,这些索引中的每一个都对应于运行的 end ,因此我将为它添加0以使for
循环更易于使用。
这是我的最终解决方案:
nonZeroIndices = find(A);
breakIndices = [0 find(diff(nonZeroIndices) > 1)];
for ii = 1:numel(breakIndices)
if ii ~= numel(breakIndices)
c{ii,:} = A(nonZeroIndices(breakIndices(ii)+1) : nonZeroIndices(breakIndices(ii+1)));
else
c{ii} = A(nonZeroIndices(breakIndices(ii)+1):end);
end
disp(c{ii})
end
运行它,您将获得所需的输出:
1 7 3 4
1 4 5 3 2 4
2 4 3 10 3 5 3 2 1
答案 1 :(得分:1)
这是一种没有循环的方法:
A = [1 7 3 4 0 0 0 0 0 0 1 4 5 3 2 4 0 0 0 0 0 0 0 2 4 3 10 3 5 3 2 1]; %// data
nz = logical(A); %// logical index of nonzeros of A
ind = find(conv(2*([false nz])-1,[1 -1],'valid')==2); %// find ends of runs of zeros
B = zeros(size(A)); B(ind) = 1; B = cumsum(B); %// integer label for each group
result = accumarray(B(nz).', A(nz).', [], @(x){x.'}); %'// nonzero elements by group
结果是行向量的单元格数组。在您的示例中,
>> celldisp(result)
result{1} =
1 7 3 4
result{2} =
1 4 5 3 2 4
result{3} =
2 4 3 10 3 5 3 2 1
答案 2 :(得分:0)
您想要的输出似乎不是矢量,而是三个单独的矢量。我将假设您希望它们作为单元格数组c{1}
的单独单元格(c{2}
,c{3}
和c
):
A = [1 7 3 4 0 0 0 0 0 0 1 4 5 3 2 4 0 0 0 0 0 0 0 2 4 3 10 3 5 3 2 1];
z = diff([0 A 0] == 0);
firstnonzero = find(z < 0);
lastnonzero = find(z > 0) - 1;
c = {};
for i = 1:numel(firstnonzero)
c{i} = A(firstnonzero(i):lastnonzero(i));
end
disp(c)