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

ここで、最初の数字は各クラスターの「開始」インデックスで、2 番目の数字は各クラスターの「終了」インデックスです。

編集:これを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

の 2 つの呼び出しをfind1 つに減らすことができます。

[output,~] = find([[v1(1);d] [-d;v1(end)]]==1);
output = reshape(output,[length(output)/2 2]);
于 2013-08-11T20:37:33.457 に答える
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 に答える