Вероятно, есть способ сделать это с реальным скользящим окном, но, поскольку мне приходилось выполнять какие-то подобные операции с вами по-другому, я буду повторно использовать функцию, которую я делал несколько лет назад, которая идеально подходит для этогопроблема в другом направлении.
В основном процесс выглядит так:
- Найти ВСЕ индексы, подтверждающие условие (x> 91 и x <97). </li>
- Найти началои остановите индексы каждой последовательной группы / интервала, найденного в шаге выше.
- Вычислите длину каждого интервала (легко с запуском и остановкой, указанными выше)
- Сбросьте слишком короткие интервалы
К настоящему времени у вас есть список интервалов (индексы запуска и остановки), проверяющих все ваши условия (уровень сигнала И длительность). Теперь вы можете:
- перестроить один вектор действительных индексов
- Создать вторичный вектор, который содержит только помеченные данные (данные
x
, которые подтвердили все условия). - display: -)
В коде это выглядит так:
%% Your inputs
load('data.mat');
time = 1:length(x);
%% Setup
winSize = 1000 ; % Fs * Duration = 100 * 10 = 1000 points
lvlmin = 91 ; % Minimum level to flag
lvlmax = 97 ; % Maximum level to flag
%% Find which interval to flag
% find all the indices where the condition is true
idx = ( x>lvlmin ) & ( x<lvlmax ) ;
% get the start and stop index of each group of consecutive indices
itBounds = get_interval_boundaries( idx ) ;
% get the length of each interval/group
itLenght = diff(itBounds,1,2)+1 ;
% only consider intervals >= winSize
it2flag = itLenght >= winSize ;
nint = sum(it2flag) ; % found 241 valid intervals out of 596.
%% Clear [idx] of the short intervals
itbad = itBounds( ~it2flag , : ) ; % keep only the intervals to discard
for k=1:size(itbad,1)
idx(itbad(k,1):itbad(k,2)) = false ;
end
%% Display
flaggedTime = time(idx) ;
flaggedData = x(idx) ;
figure
plot(time,x)
hold on
plot(flaggedTime,flaggedData,'.')
lx = [time(1) time(end)] ;
plot( lx , [lvlmin lvlmin], '-.k')
plot( lx , [lvlmax lvlmax], '-.k')
%% OR, alternatively, keep vectors the same lenght by adding NaNs
flaggedData = x ;
flaggedData(~idx) = NaN ;
figure
plot(time,x)
hold on
plot(time,flaggedData)
И предварительный просмотр того, как данные помечены:
Вам понадобится код для get_interval_boundaries.m
. Я мог бы закодировать только функциональность, необходимую в меньшем количестве кода, но, поскольку он был доступен и отлично работает, нет необходимости заново изобретать колесо:
function itbound = get_interval_boundaries(vec)
% function itbound = get_interval_boundaries(vec)
%
% This function takes a vector of index as input (or a logical index array)
% It returns a nx2 table containing on each line the first and last index
% of consecutive intervals of indexes.
% ex:
% A = [1 2 3 5 7 8 9] ;
% [itbound] = get_interval_boundaries(A)
% itbound =
% 1 3
% 5 5
% 7 9
%
% 09-Oct-2011 - Hoki: creation
% 15-Sep-2012 - Hoki: Corrected last index special case
% (return last idx instead of 0)
% 01-Sep-2014 - Hoki: Corrected first index special case
% (return [1 1] in case vec is a scalar)
%% Check vec type (logical array or direct indexing)
% Return empty vector if input is empty
itbound = [] ;
if isempty(vec)
return
end
% Check the type of input vector
if islogical(vec)
idxDirect = find(vec) ;
elseif isnumeric(vec)
idxDirect = vec ;
else
errordlg('bad type for ''vec''. Variable should be numeric or logical',mfilename,'modal')
return
end
%% Detect intervals
Npts = length(idxDirect) ;
% return [] in case vec is all [0]
if Npts == 0 ; return ; end
itbound(1,1) = idxDirect(1) ;
% return [x x] in case vec is a scalar value [x]
if Npts == 1
itbound(1,2) = idxDirect(1) ;
return
end
j=1 ;
for k = 2:Npts
if idxDirect(k)==idxDirect(k-1)+1
if k~=Npts
% Cycle the loop
continue
else
% Last point: Assign closing boundary of last interval
itbound(j,2) = idxDirect(k) ;
end
else
% Assign closing boundary of current interval
itbound(j,2) = idxDirect(k-1) ;
% Assign opening boundary of next interval
j = j + 1 ;
itbound(j,1) = idxDirect(k) ;
% If we're on the very last index, close the interval.
if k==Npts
itbound(j,2) = idxDirect(k) ;
end
end
end