在逻辑向量中查找“TRUE”簇的位置

时间:2013-08-11 20:17:52

标签: matlab

我有以下逻辑向量:

vect1 = [0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 0 0 1 1 0 0 0 1]

我想在此向量中找到所有1值“簇”以及它们的起始和结束索引。对于输出,我希望能够提出类似的东西:

5 8
13 15
18 19
23 23

其中第一个数字是每个群集的“起始”索引,第二个数字是每个群集的“结束”索引。

编辑:我能够使用Shai的答案的修改版本来使用它:

pv = [vect1 0];
sv = [0 pv(1:(end-1))];
ev = [pv(2:end) 0];
starting = find( pv - sv == 1 )
ending = find( pv - ev == 1 )

4 个答案:

答案 0 :(得分:4)

这个问题几乎与this one重复。从那里调整我的答案:

vect1 = [0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 0 0 1 1 0 0 0 1];
v1 = (vect1(:)==1);
d = diff(v1);
output = [find([v1(1);d]==1) find([d;-v1(end)]==-1)]

返回

output =

     5     8
    13    15
    18    19
    23    23

find的两次调用可以通过

减少到一次
[output,~] = find([[v1(1);d] [-d;v1(end)]]==1);
output = reshape(output,[length(output)/2 2]);

答案 1 :(得分:3)

要处理最后的1,用向量填充向量会更简单:

pv = [vect1 0];
sv = [0 pv];
ev = [pv(2:end) 0];
starting = find( pv - sv == 1 );
ending = find( pv - sv == -1 );

答案 2 :(得分:0)

这是我能想到的最简单的一个班轮

out =  [find(diff([0 vect1 0])==1); find(diff([0 vect1 0])==-1)-1]'

答案 3 :(得分:0)

在Matlab文件交换上有一个运行长度编码函数,我用它来解决这类问题。这个解决方案的好处(即rle函数)是它在没有事先知道将重复哪些值的情况下找到重复的块。

encoded = rle(vect1);
summed = cumsum(encoded{2});
isOne = encoded{1}==1;
[summed(isOne)-encoded{2}(isOne)+1;  summed(isOne)]'

请参阅: http://www.mathworks.com/matlabcentral/fileexchange/4955-rle-deencoding

或者(稍快)

blockEnds = [ find(vect1(1:end-1) ~= vect1(2:end)) length(vect1) ];
blockStarts = [ 1 blockEnds(1:end-1)+1];
isOne = vect1(blockEnds)==1;
[blockStarts(isOne); blockEnds(isOne)]'