我想使用数组中的重复段对我的元素进行分组。中断基本上取决于重复段的位置,在我的真实数据中包含约 10000 个元素,我想知道是否有更简单的方法来做到这一点。
这是一个简短的示例来说明我想要什么:
假设我有一个数组,
A=[1 5 3 4 4 4 6 9 8 8 9 5 2];
我想要的是A
闯入[1 5 3],[6 9], and [9 5 2];
使用matlab编写这个代码最简单的是什么?
谢谢。
对于矢量化解决方案,您可以找出与邻居的前向或后向差异为零的位置,然后使用bwlabel
(来自图像处理工具箱)并accumarray
收集数据。
A=[1 5 3 4 4 4 6 9 8 8 9 5 2];
d = diff(A)==0;
%# combine forward and backward difference
%# and invert to identify non-repeating elments
goodIdx = ~([d,false]|[false,d]);
%# create list of group labels using bwlabel
groupIdx = bwlabel(goodIdx);
%# distribute the data into cell arrays
%# note that the first to inputs should be n-by-1
B = accumarray(groupIdx(goodIdx)',A(goodIdx)',[],@(x){x})
编辑
如果您希望重复元素也出现在元胞数组中,请将最后两行代码替换为以下代码
groupIdx = cumsum([1,abs(diff(goodIdx))]);
B = accumarray(groupIdx',A',[],@(x){x})
编辑2
如果您还希望能够拆分相同数字的连续组,则需要计算groupIdx
如下:
groupIdx = cumsum([1,abs(diff(goodIdx))|~d.*~goodIdx(2:end)])
如果我正确理解了这个问题,这是一个可行的解决方案。它可能可以进一步优化。
A=[1 5 3 4 4 4 6 9 8 8 9 5 2];
% //First get logical array of non consecutive numbers
x = [1 (diff(A)~=0)];
for nn=1:numel(A)
if ~x(nn)
if x(nn-1)
x(nn-1)=0;
end
end
end
% //Make a cell array using the logical array
y = 1+[0 cumsum(diff(find(x))~=1)];
x(x~=0) = y;
for kk = unique(y)
B{kk} = A(x==kk);
end
B{:}