def _compute(self, start_dt, end_dt): previous_tick = self._storage.load_previous_tick(start_dt) if previous_tick is None: previous_tick_end = self._params['start'] else: previous_tick_end = previous_tick.name # Calculate ticks from the previous ticks until the interval that we are currently interested in request = [FeatureRequest.from_feature(self)] if previous_tick_end != start_dt: self._runner.compute_dataframes(request, previous_tick_end, start_dt) new_previous_tick = self._storage.load_previous_tick(start_dt) if new_previous_tick is None or new_previous_tick.empty: new_previous_tick = previous_tick # Should be up-to-date now, so get the updated latest tick # If there is still no previous tick then we have to start from the beginning if new_previous_tick is None: start = self._params['start'] elif new_previous_tick.empty: raise ValueError('This should not be possible') else: start = new_previous_tick.name + dt.timedelta(microseconds=1) return self._compute_recursion(previous_tick, start, end_dt)
def _compute(self, start_dt, end_dt): if end_dt < self._params['start']: msg = 'Can''t calculate this range as {} is before the clock start {}' raise ValueError(msg.format(end_dt, self._params['start'])) previous_tick = self._storage.load_previous_tick(start_dt) if previous_tick is None: previous_tick_end = self._params['start'] else: previous_tick_end = previous_tick.name + datetime.timedelta(microseconds=1) # Calculate ticks from the previous ticks until the interval that we are currently interested in request = [FeatureRequest.from_feature(self)] if previous_tick_end != start_dt: self._runner.compute_dataframes(request, previous_tick_end, start_dt) new_previous_tick = self._storage.load_previous_tick(start_dt) if new_previous_tick is None or new_previous_tick.empty: new_previous_tick = previous_tick else: new_previous_tick = previous_tick # Should be up-to-date now, so get the updated latest tick # If there is still no previous tick then we have to start from the beginning if new_previous_tick is None: start = self._params['start'] elif new_previous_tick.empty: raise ValueError('This should not be possible') else: start = new_previous_tick.name + datetime.timedelta(microseconds=1) clock = self._clock_feature(start, end_dt) if len(clock) == 0: # There are no ticks in this range, so nothing to do return None input = self._input_feature(clock.iloc[0]['previous'], clock.iloc[-1].name) clock['tick'] = clock.index.to_series(keep_tz=True) merged_data = pd.merge_asof(input, clock.set_index('previous', drop=False), left_index=True, right_index=True) ticks = [] for tick, df in merged_data.groupby('tick'): clock_tick = clock.loc[tick] new_previous_tick = pd.Series(self._compute_recursive_tick(clock_tick, new_previous_tick, df), name=tick) ticks.append(new_previous_tick) return pd.DataFrame([t for t in ticks if end_dt > t.name >= start_dt])