3

我想使用数组中的重复段对我的元素进行分组。中断基本上取决于重复段的位置,在我的真实数据中包含约 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编写这个代码最简单的是什么?

谢谢。

4

2 回答 2

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})

编辑2

如果您还希望能够拆分相同数字的连续组,则需要计算groupIdx如下:

 groupIdx = cumsum([1,abs(diff(goodIdx))|~d.*~goodIdx(2:end)])
于 2012-08-22T19:39:38.237 回答
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{:}
于 2012-08-22T18:37:04.647 回答