Filter data into different Phases using multiple conditions.
2 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
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 commentaires
Réponse acceptée
arich82
le 23 Sep 2015
Modifié(e) : arich82
le 24 Sep 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 commentaires
arich82
le 25 Sep 2015
I corrected the typo.
I'm glad it helps.
I still might play around with it over the weekend...
Plus de réponses (1)
Thorsten
le 23 Sep 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 commentaires
Thorsten
le 24 Sep 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
Voir également
Catégories
En savoir plus sur Visualization dans Help Center et File Exchange
Produits
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!