数据源出错:迭代正确地迭代矢量而没有for循环?

时间:2014-03-03 16:36:46

标签: matlab for-loop vectorization

大家好,我有一个新的小问题: 我使用的数据有一个奇怪的交易时间,从一天的17.00到后一天的16.15。 这意味着,例如,对于2013年3月9日这一天我使用的来源注册交易发生如下:

   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

现在第一个和第二个对我来说不正确:它们属于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;

很容易说这只会修复一系列的“最后”错误观察。在前面的示例中,这只会纠正第二个元素。我应该多次运行代码(我考虑了一个while循环),直到idx为空。使用小型系列时,这不是一个大问题,但我有多达2000万次观察,可能连续数十万次不正确。 有没有办法以矢量化的方式解决这个问题?

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  

提前感谢大家

2 个答案:

答案 0 :(得分: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

更多Crazier版本 -

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

具有各种数据的这些版本的一些平均计算运行时间 -

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

答案 1 :(得分:0)

显然我在数据源中遇到了另外3个不同的问题,我认为这些问题可能会影响到Divakar提出的例程。无论如何,我认为它太慢,所以我开始考虑另一个解决方案,并提出了一个超快速矢量化的解决方案。

鉴于我想要修改的观察属于确定的已知时间间隔,该函数只是查找落在该间隔内的每个观察并按我的意愿修改它(在我的情况下为-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