1

我有以下逻辑向量:

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

4 回答 4

4

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

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]);
于 2013-08-11T20:37:33.457 回答
3

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

pv = [vect1 0];
sv = [0 pv];
ev = [pv(2:end) 0];
starting = find( pv - sv == 1 );
ending = find( pv - sv == -1 );
于 2013-08-11T20:26:35.647 回答
0

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

out =  [find(diff([0 vect1 0])==1); find(diff([0 vect1 0])==-1)-1]'
于 2013-08-12T01:45:51.203 回答
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)]'
于 2013-08-12T01:57:04.317 回答