What I would like to do is remove entries from a list of instrument data when it is in maintenance. The maintenance data I have is a series of dates which look like this;
{{{2009, 6, 29, 10, 41, 0.}, {2009, 6, 30, 15, 26, 0.}}, {{2009, 6, 
   30, 16, 52, 0.}, {2009, 7, 1, 6, 0, 0.}}, {{2009, 7, 1, 6, 0, 
   0.}, {2009, 7, 1, 6, 2, 0.}}}
So between 29/6/2009 10:41 and 30/6/2008 15:26 the instrument was in maintenance.
The instrument data looks like this;
{{{2010, 1, 1, 6, 15, 0.}, 0.04375}, {{2010, 1, 1, 6, 30, 0.}, 
  0.04375}, {{2010, 1, 1, 6, 45, 0.}, 
  0.04375}, {{2010, 1, 1, 7, 0, 0.}, 
  0.04375}, {{2010, 1, 1, 7, 15, 0.}, 0.04375}}
With the first column being the date/time and the second the value.
What I would like is a quick (the instrument data is 100,000 records) way to remove rows from the instrument data when their date falls inside a maintenance period.
Answer
Starting with:
gaps = {{{2009, 6, 29, 10, 41, 0.}, {2009, 6, 30, 15, 26, 
     0.}}, {{2009, 6, 30, 16, 52, 0.}, {2009, 7, 1, 6, 0, 
     0.}}, {{2009, 7, 1, 6, 0, 0.}, {2009, 7, 1, 6, 2, 0.}}};
data = {{{2010, 1, 1, 6, 15, 0.}, 0.04375}, {{2010, 1, 1, 6, 30, 0.}, 
    0.04375}, {{2010, 1, 1, 6, 45, 0.}, 
    0.04375}, {{2010, 1, 1, 7, 0, 0.}, 
    0.04375}, {{2010, 1, 1, 7, 15, 0.}, 
    0.04375}, {{2009, 6, 30, 7, 26, 0.}, 0.1}};
I recommend:
maint = Interval @@ Map[AbsoluteTime, gaps, {2}];
Cases[data, {date_, _} /; ! IntervalMemberQ[maint, AbsoluteTime@date]]
Or if you prefer a form with Select like wxffles shows you could write:
makeTest[gaps_] :=
 With[{maint = Interval @@ Map[AbsoluteTime, gaps, {2}]},
   ! IntervalMemberQ[maint, AbsoluteTime @ #[[1]]] &
 ]
Select[data, makeTest @ gaps]
This should be more convenient to use for multiple "gaps" lists.
This is what I believe Murta wanted to write:
removeRanges[data_, gaps_] :=
 Module[{absData, absGaps},
  absData = AbsoluteTime /@ data[[All, 1]];
  absGaps = Interval @@ Map[AbsoluteTime, gaps, {2}];
  Pick[data, ! IntervalMemberQ[absGaps, #] & /@ absData]
 ]
Comments
Post a Comment