class_docstr: This class implements APE (absolute percent error) based detector.
  The class finds the
  
  - best forecast among multiple forecasts which can be
      passed as baselines
  - as well as optimal APE threshold to use to denote an anomaly
  
  
  This class inherits its parameters and attributes from
  
  `~greykite.detection.detector.forecast_based.BestForecast`
  
  and all methods apply here as well. The only difference is: ``param_iterable``
  is not passed but constructed during the ``__init__``.
  
  
  Parameters
  ----------
  Solely inherited from
  `~greykite.detection.detector.forecast_based.BestForecast`
  except for the input parameter `param_iterable` which is constructed in the
  ``__init__``.
  
  Attributes
  ----------
  Solely inherited from
  `~greykite.detection.detector.forecast_based.BestForecast`
docstr: Adds features to one joined dataframe. This will be used to add
  features to all joined dataframes.
  
  Parameters
  ----------
  joined_df : `pandas.DataFrame`
      An input dataframe.
  
  Returns
  -------
  joined_df : `pandas.DataFrame`
      An output dataframe, with an extra column of APE values.
code: def add_features_one_df(self, joined_df):
      """Adds features to one joined dataframe. This will be used to add
      features to all joined dataframes.
  
      Parameters
      ----------
      joined_df : `pandas.DataFrame`
          An input dataframe.
  
      Returns
      -------
      joined_df : `pandas.DataFrame`
          An output dataframe, with an extra column of APE values.
      """
  
      for col in self.value_cols + self.pred_cols:
          if col not in joined_df.columns:
              raise ValueError(
                  "f{col} was not found in joined data with columns:",
                  "{joined_df.columns}",
              )
  
      # Multivariate APE using Euclidean distance
      joined_df["ape"] = np.linalg.norm(
          joined_df[self.value_cols].values
          - joined_df[self.pred_cols].values,
          axis=1,
      ) / np.linalg.norm(joined_df[self.value_cols].values, axis=1)
  
file_path: greykite/greykite/detection/detector/ape_based.py
imports: import numpy
  from greykite.common.constants import PREDICTED_ANOMALY_COL
  from greykite.detection.detector.best_forecast import BestForecastDetector
  from greykite.detection.detector.optimizer import CalcResult
label_desc: Use image node_id 2 for calling the APEDetector obj's underlying member method code with example usage: obj.add_features_one_df(joined_df) without return types