class_docstr: Base class for a forecaster model which supports exogenous variables. Exogenous variables are known a priori, and
  they are independent of the variable being forecasted.
class_docstr_tok: ["Base","class","for","a","forecaster","model","which","supports","exogenous","variables",".","Exogenous","variables","are","known","a","priori",",","and","they","are","independent","of","the","variable","being","forecasted","."]
docstr: Transforms & resamples exogenous data and splits it into two subsets:
  one with the same timestamps as ``time_series_prev`` (``None`` if ``time_series_prev`` is ``None``),
  and one with the timestamps ``time_stamps``.
  
  :param exog_data: The exogenous data of interest.
  :param time_stamps: The timestamps of interest (either the timestamps of data, or the timestamps at which
      we want to obtain a forecast)
  :param time_series_prev: The timestamps of a time series preceding ``time_stamps`` as context. Optional.
  :return: ``(exog_data, exog_data_prev)``, where ``exog_data`` has been resampled to match the ``time_stamps``
      and ``exog_data_prev` has been resampled to match ``time_series_prev.time_stamps``.
docstr_tok: ["Transforms","&","resamples","exogenous","data","and","splits","it","into","two","subsets",":","one","with","the","same","timestamps","as","``","time_series_prev","``","(","``","None","``","if","``","time_series_prev","``","is","``","None","``",")",",","and","one","with","the","timestamps","``","time_stamps","``",".",":","param","exog_data",":","The","exogenous","data","of","interest",".",":","param","time_stamps",":","The","timestamps","of","interest","(","either","the","timestamps","of","data",",","or","the","timestamps","at","which","we","want","to","obtain","a","forecast",")",":","param","time_series_prev",":","The","timestamps","of","a","time","series","preceding","``","time_stamps","``","as","context",".","Optional",".",":","return",":","``","(","exog_data",",","exog_data_prev",")","``",",","where","``","exog_data","``","has","been","resampled","to","match","the","``","time_stamps","``","and","``","exog_data_prev","`","has","been","resampled","to","match","``","time_series_prev.time_stamps","``","."]
code: def transform_exog_data(
      self,
      exog_data: TimeSeries,
      time_stamps: Union[List[int], pd.DatetimeIndex],
      time_series_prev: TimeSeries = None,
  ) -> Union[
      Tuple[TimeSeries, TimeSeries],
      Tuple[TimeSeries, None],
      Tuple[None, None],
  ]:
      """
      Transforms & resamples exogenous data and splits it into two subsets:
      one with the same timestamps as ``time_series_prev`` (``None`` if ``time_series_prev`` is ``None``),
      and one with the timestamps ``time_stamps``.
  
      :param exog_data: The exogenous data of interest.
      :param time_stamps: The timestamps of interest (either the timestamps of data, or the timestamps at which
          we want to obtain a forecast)
      :param time_series_prev: The timestamps of a time series preceding ``time_stamps`` as context. Optional.
      :return: ``(exog_data, exog_data_prev)``, where ``exog_data`` has been resampled to match the ``time_stamps``
          and ``exog_data_prev` has been resampled to match ``time_series_prev.time_stamps``.
      """
      # Check validity
      if exog_data is None:
          if self.exog_dim is not None:
              raise ValueError(
                  f"Trained with {self.exog_dim}-dim exogenous data, but received none."
              )
          return None, None
      if self.exog_dim is None:
          raise ValueError(
              "Trained without exogenous data, but received exogenous data."
          )
      if self.exog_dim != exog_data.dim:
          raise ValueError(
              f"Trained with {self.exog_dim}-dim exogenous data, but received {exog_data.dim}-dim."
          )
  
      # Transform & resample
      exog_data = self.exog_transform(exog_data)
      if time_series_prev is not None:
          t = (
              time_series_prev.time_stamps
              + to_timestamp(time_stamps).tolist()
          )
          exog_data = exog_data.align(
              reference=t,
              aggregation_policy=self.exog_aggregation_policy,
              missing_value_policy=self.exog_missing_value_policy,
          )
          exog_data_prev, exog_data = exog_data.bisect(
              time_stamps[0], t_in_left=False
          )
      else:
          exog_data_prev = None
          exog_data = exog_data.align(
              reference=time_stamps,
              aggregation_policy=self.exog_aggregation_policy,
              missing_value_policy=self.exog_missing_value_policy,
          )
      return exog_data, exog_data_prev
  
imports: from abc import abstractmethod
  import copy
  import logging
  from typing import List, Optional, Tuple, Union
  import numpy
  import pandas
  from scipy.stats import norm
  from merlion.models.base import Config, ModelBase
  from merlion.plot import Figure
  from merlion.transform.base import TransformBase
  from merlion.transform.factory import TransformFactory
  from merlion.transform.normalize import MeanVarNormalize
  from merlion.utils.time_series import to_pd_datetime, to_timestamp, TimeSeries, AggregationPolicy, MissingValuePolicy
label_desc: Use image node_id 5 for calling the ForecasterExogBase obj's underlying member method code with example usage: obj.transform_exog_data(exog_data, time_stamps, time_series_prev) and returns: exog_data,  exog_data_prev, None,  None