Filter data into different Phases using multiple conditions.
    12 visualizaciones (últimos 30 días)
  
       Mostrar comentarios más antiguos
    
    Daan
 el 23 de Sept. de 2015
  

Hi all,
I have got data which looks like C=[0,3 0,8 0,3 1,3 0,6 1,1 3,1 5,1 3,1 0,5]. I want to split this data into 2 Phases. Phase 1 will start when >1 (condition1) AND 3 spots after this point it must be > 3(condition2). Phase 1 will end when <1. D should eventually look like [0 0 0 0 0 1 1 1 1 0].
Condition 1 can easily be tested by D=C>1. But I can't figure out how to expand the filter by condition 2? How can I achieve this?
Many Thanks, Daan
0 comentarios
Respuesta aceptada
  arich82
      
 el 23 de Sept. de 2015
        
      Editada: arich82
      
 el 24 de Sept. de 2015
  
      I think you can achieve this by a variation on run length encoding. First, encode the data based on condition 1, then use condition 2 to modify the decoding. (Note that I'm interpretting condition 2 to mean '**still** greater than 1' for three spots; let me know if this is correct).
% data
C=[0.3 0.8 0.3 1.3 0.6 1.1 3.1 5.1 3.1 0.5];
% make data nontrivial
C = [C, C]
% apply condition 1
L = C > 1
% get index of the start of each phase change
%
% note: the first index is always the start of the first phase, so
% we begin the mask with true
mask = [true, logical(diff(L))]
idx = find(mask) 
% compute the run-length of each phase
%
% note: an 'extra' index is appended to the end of the data,
% (essentially a 'phantom' phase starting past the end of the data)
% in order to get the correct length of the last phase
rl = diff([idx, numel(C)+1]) 
% extract the values associated with the run-length encoding
v = L(mask)
% apply condition 2
% i.e. require all '1' phases to also have a run-length > 3
v = v & (rl > 3)
% decode the rle
D = v(cumsum(mask))
The input C and output D are (printed columnwise for easier comparison)
>> [num2str(C(:)), repmat('  ', numel(C), 1), num2str(D(:))]
ans =
0.3  0
0.8  0
0.3  0
1.3  0
0.6  0
1.1  1
3.1  1
5.1  1
3.1  1
0.5  0
0.3  0
0.8  0
0.3  0
1.3  0
0.6  0
1.1  1
3.1  1
5.1  1
3.1  1
0.5  0
Please accept this answer if it helps, or leave a note in the comments if I've missed something.
7 comentarios
  arich82
      
 el 25 de Sept. de 2015
				I corrected the typo.
I'm glad it helps.
I still might play around with it over the weekend...
Más respuestas (1)
  Thorsten
      
      
 el 23 de Sept. de 2015
        The indices three positions after C is > 1 can be found using
 ind = find(C > 1) + 3;
Ensure that the indices are not larger than the number of elements in C
 ind = ind(ind < numel(C));
Start of phase 1
i1 = ind(find(C(ind) > 1, 1, 'first'))
Start of phase 2
 ind2 = find(C < 1);
 i2 = ind2(find(ind2 - i1 > 0, 1, 'first'));
 phase1 = zeros(size(C));
 phase1(i1:i2) = 1;
3 comentarios
  Thorsten
      
      
 el 24 de Sept. de 2015
				i = 1;
while numel(C) > 1
    %insert algorithm from above
    phase1{i} = C(i1:i2); 
    i = i + 1;
    if i2 == numel(C), C = []; else, C = C(i2+1:end); end
  end
Ver también
Categorías
				Más información sobre Visualization en Help Center y File Exchange.
			
	Productos
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!
