我想使用数组中重复的段对元素进行分组。中断主要取决于重复段的位置,在我的实际数据中包含~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编写最简单的代码是什么?
感谢。
答案 0 :(得分:3)
对于矢量化解决方案,您可以找出与邻居的前向或后向差异为零的位置,然后使用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})
<强> EDIT2 强>
如果您希望能够分割连续的相同数字组,则需要按如下方式计算groupIdx
:
groupIdx = cumsum([1,abs(diff(goodIdx))|~d.*~goodIdx(2:end)])
答案 1 :(得分:1)
如果我正确理解了问题,这是一个有效的解决方案。它可能会进一步优化。
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{:}