大家好,我有一个新的小问题: 我使用的数据有一个奇怪的交易时间,从一天的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
提前感谢大家
答案 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