Basic question: how to find range of index values

I want to find the location (range of N index values) over which a variable (mydata) holds a specific value (X)
The variable (mydata) contains many occurrences of X before the occurrence of a plateau - where the value of X is constant for N data points.
ELABORATION:
My problem is a little more complex.
mydata = [1 1 2 3 4 5 6 1 4 4 4 4 4 4 4 1 45 67 8 9 4 4 4 4 4 1 36 2 4 4 4 3 1 1 18 98 99]
I want to find the index values for the 7 (N) consecutive occurrences of '4'. I do not want to find the other occurrences of '4' i.e. one occurrence before the sequence of 7 and later one occurrence of a sequence of 5.

 採用された回答

Etienne O'Brien
Etienne O'Brien 2011 年 6 月 13 日

0 投票

Thank you everyone.
Matt's solution worked for me
S = findstr(mydata,4*ones(1,3));
However, my computer is making heavy weather of this calculation. It's taking several seconds to return the answer as it returns the starting values of sub-occurrences. Unfortunately I realise now that I don't know the precise length of the sequence. For example it could be 1100 or 1500 data points long but I do know that there will be at least 1000. Is it possible to adapt Matt's function to return the first occurrence only?
Thank you.

4 件のコメント

Matt Fig
Matt Fig 2011 年 6 月 13 日
Several seconds? What size is the data you are looking at? I tested this with data (mydata) which is 1-by-500000 and it took less than a tenth of a second.... For example:
mydata = round((rand(1,500000)>.15)*4);
N = 6; % Look for 6 4s in a row.
tic
M = findstr(mydata,4*ones(1,N));
toc
Elapsed time is 0.005884 seconds.
Etienne O'Brien
Etienne O'Brien 2011 年 6 月 14 日
Thanks Matt,
I'm not quite sure what the reason for this delay was. It has gone now. Thanks for your help with this issue. I have re-posted a somewhat related data question and would be grateful if you have time to look at it also.
Andrew Newell
Andrew Newell 2011 年 6 月 14 日
Etienne, I hope that you selected your own answer by mistake. Matt's was clearly the correct choice.
Etienne O'Brien
Etienne O'Brien 2011 年 6 月 16 日
Yes, you are correct. I am sorry.

サインインしてコメントする。

その他の回答 (6 件)

Matt Fig
Matt Fig 2011 年 6 月 13 日

3 投票

mydata = [1 1 2 3 4 5 6 1 4 4 4 4 4 4 4 1 45 67 8 9 4 4 4 4 4 1 36 2 4 4 4 3 1 1 18 98 99];
findstr(mydata,4*ones(1,7))
This finds the starting index of a sequence of 7 4s in a row. Change the 4 to a 5 to find a sequence of 7 5s in a row. Change the 7 to a 3 to find a sequence of 3 4s in a row, etc.
Note that the above will return the starting indices of all occurrences of, say, 3 4s in a row - even where those occurrences are sub-occurrences. To limit the search to only those occurrences which are exactly the length desired, simply make one more call to the function:
S = findstr(mydata,4*ones(1,3));
S = S(findstr([0 diff(S)==1 0],[0 0]))
Laura Proctor
Laura Proctor 2011 年 6 月 13 日

0 投票

If you wish to find the corresponding index values where your variable mydata is equal to X, then you can use the find command like this:
iVals = find(mydata==X);
Chirag Gupta
Chirag Gupta 2011 年 6 月 13 日

0 投票

I am not exactly clear about the question, but may be this is a starting point:
mydata = [1 1 2 3 4 5 6 1 1 45 67 8 9 1 36 2 3 1 1 18 98 99];
c = find(mydata==1)
You would probably to refine the condition inside the find, especially if your are dealing with doubles
Laura Proctor
Laura Proctor 2011 年 6 月 13 日

0 投票

The following will find the maximum run and return the index values in that run to a variable named reqVals.
I'm sure there's a tidier way to do this, but off the top of my head:
mydata = [1 1 2 3 4 5 6 1 4 4 4 4 4 4 4 1 45 67 8 9 4 4 4 4 4 1 36 2 4 4 4 3 1 1 18 98 99];
iVals = find(mydata==4);
sVals = iVals([true diff(iVals)~=1]);
eVals = iVals([diff(iVals)~=1 true]);
lVals = eVals - sVals + 1;
[num idx] = max(lVals)
reqVals = sVals(idx):eVals(idx)
Andrei Bobrov
Andrei Bobrov 2011 年 6 月 13 日

0 投票

md = mydata==4;
vf = find([true diff(md)~=0]);
idx = [vf; vf(2:end)-1 length(md)];
indexsevenfour = idx(:,diff(idx)+1== 7)';
MORE variant
idx = bsxfun(@plus,1:7,(1:length(mydata)-7)'-1);
idx(all(bsxfun(@eq,mydata(idx),4*ones(1,7)),2))
Etienne O'Brien
Etienne O'Brien 2011 年 6 月 13 日

0 投票

Thanks Laura and Andrei,
I've followed up Andrei's as it is the shorter.
I'm sorry, I'm a little lost though - I'm almost a complete beginner.
(1) I get this error message: ??? Error using ==> horzcat CAT arguments dimensions are not consistent.
(2) Could you correct me, if I'm wrong here in my interpretation.
md = mydata==4; % This finds the index values of all occurrences of '4' in the data set
vf = find([true diff(md)~=0]); % What does this do?
idx = [vf; vf(2:end)-1 length(md)]; % What does this do?
indexsevenfour = idx(:,diff(idx)+1== 7)'; % Does this provide the index values for the seven consecutive values of '4'
Thank you.

2 件のコメント

Matt Fig
Matt Fig 2011 年 6 月 13 日
See my solution above.
Laura Proctor
Laura Proctor 2011 年 6 月 13 日
I would go with Matt's response if you want to find sequence of (7) 4's in a row as that is the simplest way to find the index value of the starting point.
The other methods use logical indexing, which assign values of 1 for true and 0 for false.

サインインしてコメントする。

カテゴリ

タグ

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by