lundi 2 septembre 2019

Generate random list of timestamps within multiple time intervals in python

Is there any efficient way to generate a list of N random timeframes which do not intersect each other given the initial lower and upper bounds as well as the time intervals that these time periods should have. For example in the following case I want 10 timestamps between 09:00-17:00:

Initial start time: {datetime} YYYY-MM-DD 09:00:00
Initial end time: {datetime} YYYY-MM-DD 17:00:00
Timestamp intervals (in minutes): [32 24 4 20 40 8 27 18 3 4] 

where the first time period 32 minutes long, the next 24 and so on.

The way I am doing it at the moment is by using more or less the following code snippet:

def random_time(start, end, timeframe=None):
     sec_diff = int((end - start).total_seconds())
     secs_to_add = random.randint(0, sec_diff)
     return start + timedelta(seconds=secs_to_add)

def in_datetimes_range(self, x, starts, ends):
     return np.any((starts <= x) & (x <= ends))

n = 10   
dadate = datetime.now()
year = self.dadate.year
month = self.dadate.month
day = self.dadate.day

start = datetime(year, month, day, 9, 0, 0)
end = datetime(year, month, day, 17, 0, 0)
timeframe = [32 24 4 20 40 8 27 18 3 4]

startTimes = []
endTimes = []

for i in range(0, n):
   while True:
      startTime = random_time(start, end)
      endTime = startTime + timedelta(minutes=int(timeframe[i]))

      if startTimes:
         startTimesAsNpArray = np.array(startTimes)
         endTimesAsNpArray = np.array(endTimes)
         #check if new time period falls inside existing timeframes or if existing timeframes fall within new time period
         inner_bound = np.logical_or(in_datetimes_range(startTime, startTimesAsNpArray, endTimesAsNpArray), in_datetimes_range(endTime, startTimesAsNpArray, endTimesAsNpArray))
         outer_bound = np.logical_or(in_datetimes_range(startTimesAsNpArray, startTime, endTime), in_datetimes_range(endTimesAsNpArray, startTime, endTime))

      if not inner_bound and not outer_bound:
         startTimes.append(startTime)
         endTimes.append(endTime)
         break

but this is really inefficient and I was looking for something more reliable if possible.




Aucun commentaire:

Enregistrer un commentaire