2014-03-03 29 views
1

大家好我有一個新的小問題: 我使用有一個奇怪的交易時間推移從第一天的17:00至後一天的16.15數據。 這意味着,例如,對於2013年9月27日這一天的源我使用寄存器的交易事項如下:數據源中的錯誤:迭代地更正沒有for循環的向量?

DATE , TIME , PRICE 
09/27/2013,17:19:42,3225.00,1 #%first obs of the vector 
09/27/2013,18:37:59,3225.00,1 #%second obs of the vector 
09/27/2013,08:31:32,3200.00,1 
09/27/2013,08:36:17,3203.00,1 
09/27/2013,09:21:34,3210.50,1 #%fifth obs of the vector 

現在第一和第二OBS是不正確的,我:他們屬於9/27交易日但他們已於9月26日執行。由於我正在研究一些依賴非遞減時間的matlab函數,因此我需要解決這個問題。我使用的日期格式實際上是datenum Matlab的格式,所以我試圖解決只是從一箇中減去不正確觀察問題:

%#Call time the time vector, I can identify the 'incorrect' observations 
idx=find(diff(time)<0); 
time(idx)=time(idx)-1; 

很容易看出這隻會解決「最後」不正確一系列的觀察。在前面的例子中,這隻會糾正第二個元素。我應該多次運行代碼(我想過一段時間循環),直到idx將變爲空。這在處理小系列時不是一個大問題,但我有高達200萬的觀測值,可能有數十萬個連續不正確的觀測值。
有沒有辦法解決這個矢量化的方式?

idx=find(diff(time)<0); 
while idx 

然而,由於計算就不會那麼複雜我認爲,一個for循環可以有效地解決這個問題,我的想法是以下幾點:

[N]=size(time,1); 
for i=N:-1:1 
    if diff(time(i,:)<0) 
    time(i,:)=time(i,:)-1; 
    end 
end 

可悲的是它不似乎工作。
這是我實際使用的數據的一個例子。

735504.591157407 
735507.708030093  %# I made this up to give you an example of two consecutively wrong observations 
735507.708564815  %# This is an incorrect observation 
735507.160138889 
735507.185358796 
735507.356562500 

感謝大家提前

回答

1

明智的版本 -

for count = 1:numel(time) 
    dtime = diff([0 ;time]); 
    ind1 = find(dtime<0,1,'last')-1; 
    time(ind1) = time(ind1)-1; 
end 

更快,但是,瘋狂的版本 -

dtime = diff([0 ;time]); 
for count = 1:numel(time) 
    ind1 = find(dtime<0,1,'last')-1; 
    time(ind1) = time(ind1)-1; 
    dtime(ind1+1) = 0; 
    dtime(ind1) = dtime(ind1)-1; 
end 

更瘋狂的版本 -

dtime = diff([0 ;time]); 
ind1 = numel(dtime); 
for count = 1:numel(time) 
    ind1 = find(dtime(1:ind1)<0,1,'last')-1; 
    time(ind1) = time(ind1)-1; 
    dtime(ind1) = dtime(ind1)-1; 
end 

一些平均計算運行時間爲這些版本的各種datasizes -

Datasize 1: 3432 elements 
Version 1 - 0.069 sec 
Version 2 - 0.042 sec 
Version 3 - 0.034 sec 

Datasize 2: 20 Million elements 
Version 1 - 37029 sec 
Version 2 - 23303 sec 
Version 3 - 20040 sec 
+0

謝謝,先生,它的工作魅力,並沒有那麼慢。我只是在20M觀測系列上運行它。 – Gio

+0

庫爾!我對這三個版本的運行時間很感興趣。你能爲他們發佈tic-toc運行時?如果不是所有三個,至少在最後兩個版本? – Divakar

+0

我實際上可以循環這三個今晚,並給你明天的結果。無論如何,真的很好的答案,恭喜! – Gio

0

因此很明顯,我在我認爲可能stucked常規Divakar提出的數據源3個不同的問題。無論如何,我認爲它太慢了,所以我開始思考另一種解決方案,並提出了一個超級快速矢量化的解決方案。

鑑於意見我想改變下跌的時間的功能,只是看每個觀測落在該區間,並修改它,因爲我想知道確定的時間間隔(在我的情況-1)。

function [ datetime ] = correct_date(datetime,starttime, endtime) 
%#datetime is my vector of dates and times in matlab numerical format 
%#starttime is the starting hour of the interval expressed in datestr format. e.g. '17:00:00' 
%#endtime is the ending hour of the interval expressed in datestr format. e.g. '23:59:59' 

if (nargin < 1) || (nargin > 3), 
    error('Requires 1 to 3 input arguments.') 
end 
% default values 
if nargin == 1, 
    starttime='17:00'; 
    endtime='23:59:59'; 
elseif nargin == 2, 
    endtime='23:59:59'; 
end 

tvec=[datenum(starttime) datenum(endtime)]; 
tvec=tvec-floor(tvec); %#As I am working on multiples days I need to isolate only HH:MM:SS for my interval limits 
temp=datetime-floor(datetime);   %#same motivation as in the previous line 
idx=find(temp>=tvec(1)&temp<=tvec(2)); %#logical find the indices 
datetime(idx)=datetime(idx)-1;   %#modify them as I want 
clear tvec temp idx 
end