非常に大量のデータをフィルター処理するプログラムをMATLABで作成しています(MATLABを使用する必要があり、実際にはMEXを使用できません)。
実装する必要のあるフィルターの1つでは、タイムスタンプベクトルと、他のタイムスタンプが発生しない既知の「不良」時間のリストを比較する必要があります。
典型的なタイムスタンプベクトルには約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のタイムスタンプジョブの場合、この問題の計算には1時間かかることがあります。
私は、このタイプの問題を典型的なCore-i7ワークステーションで2分以内に解決し、このフィルターがこの多くの時間のエントリで実行可能になるようにしたいと考えています。
このコードの動作バージョンを含めました。bsxfun()
コードのベクトル化や役立つ関数などは理解していますが、このフィルターに必要な効率のタイプに比べると、改善はわずかです。
この問題を非常に効率的に解決するための非常に賢い方法はありますか?どんな助けでも大歓迎です。
PS以下のコードは完全です。問題の設定に必要なすべてのデータを生成し、それを解決します(非常にゆっくりですが!)。変数をより大きなもの(1,000,000など)に変更してNO_OF_TIMESTAMPS
、クロールを監視します。
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