Otimização do filtro de registro de data e hora no MATLAB - Trabalhando com conjuntos de dados muito grandes
Eu estou escrevendo um programa em MATLAB (deve usar o MATLAB e realmente não posso usar um MEX) para filtrar grandes quantidades de dados.
Um dos filtros que preciso implementar exige que eu compare um vetor de carimbo de data / hora com uma lista de tempos "ruins" conhecidos em torno dos quais outros carimbos de data e hora não podem ocorrer.
Um vetor típico de timestamp tem cerca de 2.000.000 entradas, e eu tenho uma lista de cerca de 300.000 "maus momentos".
Aqui está um exemplo de trabalho, seTIME=[1, 2.3, 5.5, 9.1, 10];
eBAD_TIMES=[5.2, 9.3];
e nós temos uma tolerânciatolerance=0.25;
, então todos os timestamps emTIME
entre4.95 and 5.45
e9.05 and 9.55
deve ser apagado. Isso significa que o vetor limpoTIME_CLEAN
deve ser igual aTIME_CLEAN=[1, 2.3, 5.5, 10];
.
Este problema é simples de resolver e resolvi-o em cerca de 4 ou 5 maneiras diferentes. No entanto, para um trabalho de registro de data e hora de 1.000.000, esse problema pode levar uma hora para ser computado facilmente.
Eu estou olhando para resolver este tipo de problema em menos de 2 minutos em uma estação de trabalho Core-i7 típica para este filtro ser viável com este muitas entradas de tempo.
Eu incluí uma versão funcional deste código. Eu entendo vetorização de código e funções comobsxfun()
pode ajudar, mas a melhoria é marginal em relação ao tipo de eficiência que eu preciso para este filtro.
Existem maneiras muito inteligentes de resolver este problema de uma forma muito eficiente? Qualquer ajuda seria muito apreciada.
P.S. O código abaixo está completo; Ele gera todos os dados necessários para configurar o problema e resolve-lo (embora muito lentamente!). Mudar oNO_OF_TIMESTAMPS
variável para algo maior (como 1.000.000) para assisti-lo rastejar!
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