class_docstr: This class enables anomaly detection algorithms which use baseline
  forecasts in their logic.
  
  The class assumes that for a given dataset (`df`) which can for example include
  timestamps and observed values for a timeseries as well as anomaly labels (optional),
  a number of (say k) forecasts are given.
  The goal is to use those k forecasts as baselines to detect anomalies.
  
  To that end this class implements joining of the k forecasts with the observed
  data (`df`), thus producing k joined dataframes.
  
  This class facilitates the join by implementing it by using the input `join_cols`
  using its `join_with_forecasts` method within the class.
  In order to use this class user only required to implement these three methods:
  
      - ``add_features_one_df``: Note that the class uses this method to fully implement
          ``add_features`` because the class can assume that the same function can
          be used for all k forecasts.
      - ``calc_with_param``: the prediction logic, assuming the optimal param
          is determined
      - ``fit``: The fit method
  
  This class also already implements ``prep_df_for_predict`` which is basically
  a combination of
  
  - Joining with baselines: ``join_with_forecasts``
  - Adding features: ``add_features``
  
  In this way, with minimal implementation, one can implement a large variety of
  "forecast based" anomaly detectors.
  
  
  Parameters
  ----------
  value_cols : `list` [`str`] or None
      The columns for the response metric (which can be multivariate).
      If not None, and also ``pred_cols`` (below) also not None, we expect them
      to be ordered consistently.
  pred_cols : `list` [`str`] or None
      The columns for the response metric (which can be multivariate).
      If not None, and also ``value_cols`` (above) also not None, we expect them
      to be ordered consistently.
  is_anomaly_col : `str` or None
  join_cols : `list` [`str`] or None
  reward : See docstring for
      `~/greykite.detection.detector.detector.Detector`
  anomaly_percent_dict : See docstring for
      `~/greykite.detection.detector.detector.Detector`
  param_iterable : See docstring for
      `~/greykite.detection.detector.detector.Detector`
  
  Attributes
  ----------
  Solely inherited from `~/greykite.detection.detector.detector.Detector`
docstr: Joins data with forecasts.
  This will be used both in training and prediction phases.
  Parameters
  ----------
  forecast_dfs : `dict` [`str`: `pandas.DataFrame`] or None, default None
      Dict of baselines (forecasts) to be joined with observed data given
      in ``df``.
      If ``df`` is None, no join is needed and ``forecast_dfs`` are
      returned.
  df : `pandas.DataFrame` or None, default None
      A dataframe which includes the observed data and potentially the
      observed labels.
      If None, it is assumed that the ``forecast_dfs``
      list has already been joined or has enough information to fit.
  
  Returns
  -------
  result : `list` [`pandas.DataFrame`]
      The list of baselines (forecasts) after being joined with ``df`` (if needed).
docstr_tok: ["Joins","data","with","forecasts",".","This","will","be","used","both","in","training","and","prediction","phases",".","Parameters","--","--","--","--","--","forecast_dfs",":","`","dict","`","[","`","str","`",":","`","pandas.DataFrame","`","]","or","None",",","default","None","Dict","of","baselines","(","forecasts",")","to","be","joined","with","observed","data","given","in","``","df","``",".","If","``","df","``","is","None",",","no","join","is","needed","and","``","forecast_dfs","``","are","returned",".","df",":","`","pandas.DataFrame","`","or","None",",","default","None","A","dataframe","which","includes","the","observed","data","and","potentially","the","observed","labels",".","If","None",",","it","is","assumed","that","the","``","forecast_dfs","``","list","has","already","been","joined","or","has","enough","information","to","fit",".","Returns","--","--","--","-","result",":","`","list","`","[","`","pandas.DataFrame","`","]","The","list","of","baselines","(","forecasts",")","after","being","joined","with","``","df","``","(","if","needed",")","."]
code: def join_with_forecasts(self, forecast_dfs, df=None):
      """Joins data with forecasts.
      This will be used both in training and prediction phases.
      Parameters
      ----------
      forecast_dfs : `dict` [`str`: `pandas.DataFrame`] or None, default None
          Dict of baselines (forecasts) to be joined with observed data given
          in ``df``.
          If ``df`` is None, no join is needed and ``forecast_dfs`` are
          returned.
      df : `pandas.DataFrame` or None, default None
          A dataframe which includes the observed data and potentially the
          observed labels.
          If None, it is assumed that the ``forecast_dfs``
          list has already been joined or has enough information to fit.
  
      Returns
      -------
      result : `list` [`pandas.DataFrame`]
          The list of baselines (forecasts) after being joined with ``df`` (if needed).
      """
  
      # If either `df` or `self.join_cols` is None, we assume data is joined
      # already or has enough info already
      if df is None or self.join_cols is None:
          return forecast_dfs
  
      joined_dfs = {}
      for k, forecast_df in forecast_dfs.items():
          joined_dfs[k] = df.merge(
              forecast_df, how="inner", on=self.join_cols
          )
  
      return joined_dfs
  
imports: from greykite.detection.detector.detector import Detector
label_desc: Use image node_id 2 for calling the ForecastBasedDetector obj's underlying member method code with example usage: obj.join_with_forecasts(forecast_dfs, df) and returns: joined_dfs, forecast_dfs