def _set_predict_start_date(self, start): dates = self.data.dates if dates is None: return if start > len(dates): raise ValueError("Start must be <= len(endog)") if start == len(dates): self.data.predict_start = datetools._date_from_idx(dates[-1], 1, self.data.freq) elif start < len(dates): self.data.predict_start = dates[start] else: raise ValueError("Start must be <= len(dates)")
def test_date_from_idx(): d1 = datetime(2008, 12, 31) idx = 15 npt.assert_equal(_date_from_idx(d1, idx, 'Q'), datetime(2012, 9, 30)) npt.assert_equal(_date_from_idx(d1, idx, 'A'), datetime(2023, 12, 31)) npt.assert_equal(_date_from_idx(d1, idx, 'B'), datetime(2009, 1, 21)) npt.assert_equal(_date_from_idx(d1, idx, 'D'), datetime(2009, 1, 15)) npt.assert_equal(_date_from_idx(d1, idx, 'W'), datetime(2009, 4, 12)) npt.assert_equal(_date_from_idx(d1, idx, 'M'), datetime(2010, 3, 31))
def test_date_from_idx(): d1 = datetime(2008, 12, 31) idx = 15 npt.assert_equal(_date_from_idx(d1, idx, "Q"), datetime(2012, 9, 30)) npt.assert_equal(_date_from_idx(d1, idx, "A"), datetime(2023, 12, 31)) npt.assert_equal(_date_from_idx(d1, idx, "B"), datetime(2009, 1, 21)) npt.assert_equal(_date_from_idx(d1, idx, "D"), datetime(2009, 1, 15)) npt.assert_equal(_date_from_idx(d1, idx, "W"), datetime(2009, 4, 12)) npt.assert_equal(_date_from_idx(d1, idx, "M"), datetime(2010, 3, 31))
def _get_predict_end(self, end): """ See _get_predict_start for more information. Subclasses do not need to define anything for this. """ out_of_sample = 0 # will be overwritten if needed if end is None: end = len(self.endog) - 1 dates = self._data.dates if isinstance(end, str): if dates is None: raise ValueError("Got a string for end and dates is None") try: dtend = self._str_to_date(end) self._data.predict_end = dtend end = dates.indexMap[dtend] except ImportError as err: # make sure timeseries isn't the prob raise ImportError(err) except KeyError as err: # end is greater than dates[-1]...probably if dtend > self._data.dates[-1]: end = len(self.endog) - 1 freq = self._data.freq out_of_sample = datetools._idx_from_dates(dates[-1], dtend, freq) else: raise err self._make_predict_dates() # attaches self._data.predict_dates elif isinstance(end, int) and dates is not None: try: self._data.predict_end = dates[end] except IndexError as err: nobs = len(self.endog) - 1 # as an index out_of_sample = end - nobs end = nobs freq = self._data.freq self._data.predict_end = datetools._date_from_idx(dates[-1], out_of_sample, freq) self._make_predict_dates() elif isinstance(end, int): nobs = len(self.endog) - 1 # is an index if end > nobs: out_of_sample = end - nobs end = nobs return end, out_of_sample
def _get_predict_end(self, end): """ See _get_predict_start for more information. Subclasses do not need to define anything for this. """ out_of_sample = 0 # will be overwritten if needed if end is None: # use data for ARIMA - endog changes end = len(self.data.endog) - 1 dates = self.data.dates freq = self.data.freq if isinstance(end, str) or (dates is not None and isinstance(end, type(dates[0]))): if dates is None: raise ValueError("Got a string or date for `end` and `dates` is None") if isinstance(end, str): dtend = self._str_to_date(end) else: dtend = end # end could be a pandas TimeStamp not a datetime self.data.predict_end = dtend try: end = self._get_dates_loc(dates, dtend) except KeyError as err: # end is greater than dates[-1]...probably if dtend > self.data.dates[-1]: end = len(self.data.endog) - 1 freq = self.data.freq out_of_sample = datetools._idx_from_dates(dates[-1], dtend, freq) else: if freq is None: raise ValueError("There is no frequency for these " "dates and date %s is not in dates " "index. Try giving a date that is in " "the dates index or use an integer." % dtend) else: #pragma: no cover raise err # should never get here self._make_predict_dates() # attaches self.data.predict_dates elif isinstance(end, int) and dates is not None: try: self.data.predict_end = dates[end] except IndexError as err: nobs = len(self.data.endog) - 1 # as an index out_of_sample = end - nobs end = nobs if freq is not None: self.data.predict_end = datetools._date_from_idx(dates[-1], out_of_sample, freq) elif out_of_sample <= 0: # have no frequency but are in sample #TODO: what error to catch here to make sure dates is #on the index? try: self.data.predict_end = self._get_dates_loc(dates, end) except KeyError: raise else: self.data.predict_end = end + out_of_sample self.data.predict_start = self._get_dates_loc(dates, self.data.predict_start) self._make_predict_dates() elif isinstance(end, int): nobs = len(self.data.endog) - 1 # is an index if end > nobs: out_of_sample = end - nobs end = nobs elif freq is None: # should have a date with freq = None raise ValueError("When freq is None, you must give an integer " "index for end.") else: raise ValueError("no rule for interpreting end") return end, out_of_sample
class TimeSeriesModel(base.LikelihoodModel): __doc__ = _tsa_doc % {"model" : _model_doc, "params" : _generic_params, "extra_params" : base._missing_param_doc} def __init__(self, endog, exog=None, dates=None, freq=None, missing='none'): super(TimeSeriesModel, self).__init__(endog, exog, missing=missing) self._init_dates(dates, freq) def _init_dates(self, dates, freq): if dates is None: dates = self.data.row_labels if dates is not None: if (not isinstance(dates[0], datetime.datetime) and isinstance(self.data, data.PandasData)): raise ValueError("Given a pandas object and the index does " "not contain dates") if not freq: try: freq = datetools._infer_freq(dates) except: raise ValueError("Frequency inference failed. Use `freq` " "keyword.") dates = Index(dates) self.data.dates = dates self.data.freq = _check_freq(freq) #TODO: drop if can get info from dates #TODO: still gonna need some more sophisticated handling here def _get_exog_names(self): return self.data.xnames def _set_exog_names(self, vals): if not isinstance(vals, list): vals = [vals] self.data.xnames = vals #overwrite with writable property for (V)AR models exog_names = property(_get_exog_names, _set_exog_names) def _str_to_date(self, date): """ Takes a string and returns a datetime object """ return datetools.date_parser(date) def _set_predict_start_date(self, start): dates = self.data.dates if dates is None: return if start > len(dates): raise ValueError("Start must be <= len(endog)") if start == len(dates): self.data.predict_start = datetools._date_from_idx(dates[-1], start, self.data.freq) elif start < len(dates): self.data.predict_start = dates[start] else: raise ValueError("Start must be <= len(dates)") def _get_predict_start(self, start): """ Returns the index of the given start date. Subclasses should define default behavior for start = None. That isn't handled here. Start can be a string or an integer if self.data.dates is None. """ dates = self.data.dates if isinstance(start, str): if dates is None: raise ValueError("Got a string for start and dates is None") try: dtstart = self._str_to_date(start) self.data.predict_start = dtstart # for pandas 0.7.x vs 0.8.x if hasattr(dates, 'indexMap'): # 0.7.x start = dates.indexMap[dtstart] else: start = dates.get_loc(dtstart) except: # this catches all errors in the above.. #FIXME to be less greedy raise ValueError("Start must be in dates. Got %s | %s" % (str(start), str(dtstart))) self._set_predict_start_date(start) return start def _get_predict_end(self, end): """ See _get_predict_start for more information. Subclasses do not need to define anything for this. """ out_of_sample = 0 # will be overwritten if needed if end is None: # use data for ARIMA - endog changes end = len(self.data.endog) - 1 dates = self.data.dates if isinstance(end, str): if dates is None: raise ValueError("Got a string for end and dates is None") try: dtend = self._str_to_date(end) self.data.predict_end = dtend # for pandas 0.7.x vs 0.8.x if hasattr(dates, 'indexMap'): # 0.7.x end = dates.indexMap[dtend] else: end = dates.get_loc(dtend) except KeyError, err: # end is greater than dates[-1]...probably if dtend > self.data.dates[-1]: end = len(self.data.endog) - 1 freq = self.data.freq out_of_sample = datetools._idx_from_dates(dates[-1], dtend, freq) else: raise err self._make_predict_dates() # attaches self.data.predict_dates elif isinstance(end, int) and dates is not None: try: self.data.predict_end = dates[end] except IndexError, err: nobs = len(self.data.endog) - 1 # as an index out_of_sample = end - nobs end = nobs freq = self.data.freq self.data.predict_end = datetools._date_from_idx(dates[-1], out_of_sample, freq)
end = len(self.endog) - 1 freq = self._data.freq out_of_sample = datetools._idx_from_dates(dates[-1], dtend, freq) else: raise err self._make_predict_dates() # attaches self._data.predict_dates elif isinstance(end, int) and dates is not None: try: self._data.predict_end = dates[end] except IndexError, err: nobs = len(self.endog) - 1 # as an index out_of_sample = end - nobs end = nobs freq = self._data.freq self._data.predict_end = datetools._date_from_idx(dates[-1], out_of_sample, freq) self._make_predict_dates() elif isinstance(end, int): nobs = len(self.endog) - 1 # is an index if end > nobs: out_of_sample = end - nobs end = nobs return end, out_of_sample def _make_predict_dates(self): from pandas import DateRange data = self._data dtstart = data.predict_start
class TimeSeriesModel(base.LikelihoodModel): __doc__ = _tsa_doc % { "model": _model_doc, "params": _generic_params, "extra_params": _missing_param_doc, "extra_sections": "" } def __init__(self, endog, exog=None, dates=None, freq=None, missing='none'): super(TimeSeriesModel, self).__init__(endog, exog, missing=missing) self._init_dates(dates, freq) def _init_dates(self, dates, freq): if dates is None: dates = self.data.row_labels if dates is not None: if (not isinstance(dates[0], datetime.datetime) and isinstance(self.data, data.PandasData)): raise ValueError("Given a pandas object and the index does " "not contain dates") if not freq: try: freq = datetools._infer_freq(dates) except: raise ValueError("Frequency inference failed. Use `freq` " "keyword.") dates = Index(dates) self.data.dates = dates if freq: try: #NOTE: Can drop this once we move to pandas >= 0.8.x _freq_to_pandas[freq] except: raise ValueError("freq %s not understood" % freq) self.data.freq = freq def _get_exog_names(self): return self.data.xnames def _set_exog_names(self, vals): if not isinstance(vals, list): vals = [vals] self.data.xnames = vals #overwrite with writable property for (V)AR models exog_names = property(_get_exog_names, _set_exog_names) def _get_dates_loc(self, dates, date): if hasattr(dates, 'indexMap'): # 0.7.x date = dates.indexMap[date] else: date = dates.get_loc(date) try: # pandas 0.8.0 returns a boolean array len(date) from numpy import where date = where(date)[0].item() except TypeError: # this is expected behavior pass return date def _str_to_date(self, date): """ Takes a string and returns a datetime object """ return datetools.date_parser(date) def _set_predict_start_date(self, start): dates = self.data.dates if dates is None: return if start > len(dates): raise ValueError("Start must be <= len(endog)") if start == len(dates): self.data.predict_start = datetools._date_from_idx( dates[-1], start, self.data.freq) elif start < len(dates): self.data.predict_start = dates[start] else: raise ValueError("Start must be <= len(dates)") def _get_predict_start(self, start): """ Returns the index of the given start date. Subclasses should define default behavior for start = None. That isn't handled here. Start can be a string or an integer if self.data.dates is None. """ dates = self.data.dates if isinstance(start, str): if dates is None: raise ValueError("Got a string for start and dates is None") dtstart = self._str_to_date(start) self.data.predict_start = dtstart try: start = self._get_dates_loc(dates, dtstart) except KeyError: raise ValueError("Start must be in dates. Got %s | %s" % (str(start), str(dtstart))) self._set_predict_start_date(start) return start def _get_predict_end(self, end): """ See _get_predict_start for more information. Subclasses do not need to define anything for this. """ out_of_sample = 0 # will be overwritten if needed if end is None: # use data for ARIMA - endog changes end = len(self.data.endog) - 1 dates = self.data.dates freq = self.data.freq if isinstance(end, str): if dates is None: raise ValueError("Got a string for end and dates is None") try: dtend = self._str_to_date(end) self.data.predict_end = dtend end = self._get_dates_loc(dates, dtend) except KeyError, err: # end is greater than dates[-1]...probably if dtend > self.data.dates[-1]: end = len(self.data.endog) - 1 freq = self.data.freq out_of_sample = datetools._idx_from_dates( dates[-1], dtend, freq) else: if freq is None: raise ValueError("There is no frequency for these " "dates and date %s is not in dates " "index. Try giving a date that is in " "the dates index or use an integer." % dtend) else: #pragma: no cover raise err # should never get here self._make_predict_dates() # attaches self.data.predict_dates elif isinstance(end, int) and dates is not None: try: self.data.predict_end = dates[end] except IndexError, err: nobs = len(self.data.endog) - 1 # as an index out_of_sample = end - nobs end = nobs if freq is not None: self.data.predict_end = datetools._date_from_idx( dates[-1], out_of_sample, freq) elif out_of_sample <= 0: # have no frequency but are in sample #TODO: what error to catch here to make sure dates is #on the index? try: self.data.predict_end = self._get_dates_loc(dates, end) except KeyError: raise else: self.data.predict_end = end + out_of_sample self.data.predict_start = self._get_dates_loc( dates, self.data.predict_start)