Оптимизация фильтра меток времени в MATLAB - Работа с очень большими наборами данных
Я пишу программу на MATLAB (должна использовать MATLAB и не может использовать MEX) для фильтрации очень больших объемов данных.
Один из фильтров, которые мне нужно реализовать, требует, чтобы я сравнивал вектор метки времени со списком известных «плохих» время, когда другие временные метки не могут возникнуть.
Типичный вектор метки времени содержит около 2 000 000 записей, а у меня есть список из 300 000 «плохих времен».
Вот рабочий пример, еслиTIME=[1, 2.3, 5.5, 9.1, 10];
, а такжеBAD_TIMES=[5.2, 9.3];
и у нас есть терпимостьtolerance=0.25;
тогда все отметки времени вTIME
между4.95 and 5.45
а также9.05 and 9.55
должны быть стерты. Это означает, что очищенный векторTIME_CLEAN
должно быть равноTIME_CLEAN=[1, 2.3, 5.5, 10];
.
Эту проблему легко решить, и я решил ее примерно 4 или 5 различными способами. Однако для задания с отметкой в 1 000 000 единиц времени эта проблема может легко занять один час.
Я собираюсь решить эту проблему менее чем за 2 минуты на типичной рабочей станции Core-i7, чтобы этот фильтр был жизнеспособным с таким количеством записей времени.
Я включил рабочую версию этого кода. Я понимаю векторизацию кода и такие функции, какbsxfun()
может помочь, но улучшение незначительно по сравнению с типом эффективности, который мне нужен для этого фильтра.
Есть ли какие-нибудь очень умные способы решить эту проблему очень эффективным способом? Любая помощь будет принята с благодарностью.
Постскриптум Код ниже завершен; он генерирует все данные, необходимые для установки проблемы, и решает ее (хотя ОЧЕНЬ медленно!). ИзменитьNO_OF_TIMESTAMPS
переменная к чему-то большему (например, 1 000 000), чтобы посмотреть его ползти!
clear all %% CLEAR WORKSPACE
close all %% CLOSE FIGURES
clc %% CLEAR COMMAND WINDOW
NO_OF_TIMESTAMPS=10000; %% NUMBER OF TIMESTAMPS IN ORIGINAL DATA
TOLERANCE=2; %% TOLERANCE AROUND TIMESTAMP
A=sort(randi(NO_OF_TIMESTAMPS/10,NO_OF_TIMESTAMPS,1)); %% GENERATE ARTIFICIAL TIMESTAMPS
B=unique(sort(round(randi([NO_OF_TIMESTAMPS/2,NO_OF_TIMESTAMPS*5],[NO_OF_TIMESTAMPS/10,1])/10))); %% GENERATE ARTIFICIAL LIST OF BAD TIMESTAMPS
B_LB=B-TOLERANCE; %% CREATE A LIST OF LOWERBOUND BAD TIMESTAMPS
B_UB=B+TOLERANCE; %% CREATE A LIST OF UPPERBPUND BAD TIMESTAMPS
B_RANGE=[B_LB B_UB]; %% AUGMENTED MATRIX COMPOSED OF VECTORS B_LB and B_UB
A_ROWS=size(A,1); %% SIZE OF A;
B_ROWS=size(B,1); %% SIZE OF B;
tic; %% START TIMER
A_TO_CLEAN=ones(A_ROWS,1); %% BOOLEAN VECTOR TO BE USED IN FILTERING
for ii=1:A_ROWS
for jj=1:B_ROWS
if A(ii)>=B_RANGE(jj,1) && A(ii)<=B_RANGE(jj,2) %% CHECK EACH MEMBER OF A VERSUS EACH MEMBER OF B_RANGE
A_TO_CLEAN(ii)=0; %% SET INDEX VECTOR A_TO_CLEAN = 0 SO THAT WE CAN DELETE LATER
break; %% A(ii) CAN ONLY BE ERASED ONCE, SO BREAK jj LOOP AND GO TO NEXT ii
end
end
end
CLEAN=A(~~A_TO_CLEAN); %% DELETE A VIA LOGICAL INDEXING
toc; %% END TIMER
clearvars -except A B_RANGE CLEAN %% ONLY SHOW RELEVANT VARIABLES