A second basic 'Find' question
1 visualización (últimos 30 días)
Mostrar comentarios más antiguos
I want to identify starting point of a range of values whereby the first value is greater than or equal to X and all subsequent values are greater than another value (Y), which smaller than X. The exact length of the range isn't known exactly (it has at least N points) no other data range of similar length or longer occurs within the data set.
For example: 1, 2, 3, 4, 5,6,3.5,3.1, 7,6,8,6,5,3,1,2,3,4, X=4 Y=3 N=5 I want to find the range which starts greater than or equal to 4 and doesn't fall below 3. I know that there are at least 5 data points within the range of interest.
0 comentarios
Respuesta aceptada
Matt Fig
el 15 de Jun. de 2011
idx = findstr([0 data>=X],[0 1]);
idx = idx(ismembc(idx,findstr(data>Y,ones(1,N))))
3 comentarios
Más respuestas (2)
Andrew Newell
el 14 de Jun. de 2011
My initial response was not very robust, so I have completely rewritten it:
data = data(:);
% Find how many adjacent terms are > Y
I = data>Y;
I = conv(double(I),ones(N,1));
I = I(N:end);
% Select elements > X and return length of sequence
I = I.*(data>=X);
% See if any sequences are long enough and display results
i1 = find(I>=N,1,'first');
if any(i1)
i2 = i1+I(i1)-1;
disp(['Index range = ',num2str(i1),':',num2str(i2)])
disp(['Selected data = ',num2str(data(i1:i2)')])
else
disp('No sequence found.')
end
2 comentarios
Andrei Bobrov
el 14 de Jun. de 2011
I1 = find(data == X,1);
X1 = data(I1:end) > Y;
xf = find([true diff(X1)~=0]);
idx = [xf; xf(2:end)-1 length(X1)];
idx(:,X1(idx(1,:))==0)=[];
idx1 = idx + I1 -1;
[non,I] = max(diff(idx1));
out = data(idx1(1,I):idx1(2,I));
MORE
idx = bsxfun(@plus,1:(N+1),(0:length(data)-N-1)');
ii = find(data==X,1);
id = idx(ii:end,:);
I = find(all(data(id) > Y,2));
out = data(id(I(1)):id(I(end)+N))
EDIT after comments of Andrew Newell. Very much thanks Andrew!
idx = bsxfun(@plus,1:(N+1),(0:length(data)-N-1)');
ii = find(data>=X,1);
id = idx(ii:end,:);
I = find(any(data(id) > Y,2));
out = data(id(I(1)):id(I(end)));
MORE variant (after last comments of Andrew Newell)
data = data(:);
dg3 = data > Y;
dge4 = data >= X;
xstrts = [true; diff(dge4)~=0]&dge4;
yends = flipud([true; diff(flipud(dg3))~=0])&dg3;
ii = [find(xstrts) find(yends) ];
out = cell2mat(arrayfun(@(x)data(ii(x,1):ii(x,2))',1:size(ii,1),'un',0));
2 comentarios
Andrew Newell
el 15 de Jun. de 2011
Try this test example:
data = rand(1,10000); data(101:105)=[4.1 3.3 3.3 3.3 3.3];
X=4; Y=3; N=5;
Andrew Newell
el 15 de Jun. de 2011
You're welcome! Here's another:
data = rand(1,1000); data(101:105)=[4.1 3.3 3.3 3.3 3.3]; data(1:4) = [4.1 3.3 3.3 3.3];
X=4; Y=3; N=5;
Ver también
Categorías
Más información sobre Classification en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!