class_docstr: Class for benchmarking multiple ForecastConfig on a rolling window basis.
  
  Attributes
  ----------
  df : `pandas.DataFrame`
      Timeseries data to forecast.
      Contains columns [`time_col`, `value_col`], and optional regressor columns.
      Regressor columns should include future values for prediction.
  
  configs : `Dict` [`str`,  `ForecastConfig`]
      Dictionary of model configurations.
      A model configuration is a ``ForecastConfig``.
      See :class:`~greykite.framework.templates.autogen.forecast_config.ForecastConfig` for details on
      valid ``ForecastConfig``.
      Validity of the ``configs`` for benchmarking is checked via the ``validate`` method.
  
  tscv : `~greykite.sklearn.cross_validation.RollingTimeSeriesSplit`
      Cross-validation object that determines the rolling window evaluation.
      See :class:`~greykite.sklearn.cross_validation.RollingTimeSeriesSplit` for details.
      The ``forecast_horizon`` and ``periods_between_train_test`` parameters of ``configs`` are
      matched against that of ``tscv``. A ValueError is raised if there is a mismatch.
  
  forecaster : `~greykite.framework.templates.forecaster.Forecaster`
      Forecaster used to create the forecasts.
  
  is_run : bool, default False
      Indicator of whether the `run` method is executed.
      After executing `run`, this indicator is set to True.
      Some class methods like ``get_forecast`` requires ``is_run`` to be True
      to be executed.
  
  result : `dict`
      Stores the benchmarking results. Has the same keys as ``configs``.
  
  forecasts : `pandas.DataFrame`, default None
      Merged DataFrame of forecasts, upper and lower confidence interval for all
      input ``configs``. Also stores train end date and forecast step for each prediction.
docstr: Extracts forecasts, upper and lower confidence interval for each individual
  config. This is saved as a ``pandas.DataFrame`` with the name
  ``rolling_forecast_df`` within the corresponding config of ``self.result``.
  e.g. if config key is "silverkite", then the forecasts are stored in
  ``self.result["silverkite"]["rolling_forecast_df"]``.
  
  This method also constructs a merged DataFrame of forecasts,
  upper and lower confidence interval for all input ``configs``.
docstr_tok: ["Extracts","forecasts",",","upper","and","lower","confidence","interval","for","each","individual","config",".","This","is","saved","as","a","``","pandas.DataFrame","``","with","the","name","``","rolling_forecast_df","``","within","the","corresponding","config","of","``","self.result","``",".","e.g",".","if","config","key","is","``","silverkite","''",",","then","the","forecasts","are","stored","in","``","self.result","[","``","silverkite","''","]","[","``","rolling_forecast_df","''","]","``",".","This","method","also","constructs","a","merged","DataFrame","of","forecasts",",","upper","and","lower","confidence","interval","for","all","input","``","configs","``","."]
code: def extract_forecasts(self):
      """Extracts forecasts, upper and lower confidence interval for each individual
      config. This is saved as a ``pandas.DataFrame`` with the name
      ``rolling_forecast_df`` within the corresponding config of ``self.result``.
      e.g. if config key is "silverkite", then the forecasts are stored in
      ``self.result["silverkite"]["rolling_forecast_df"]``.
  
      This method also constructs a merged DataFrame of forecasts,
      upper and lower confidence interval for all input ``configs``.
      """
      if not self.is_run:
          raise ValueError(
              "Please execute 'run' method to create forecasts."
          )
  
      merged_df = pd.DataFrame()
      for config_name, config in self.result.items():
          rolling_evaluation = config["rolling_evaluation"]
          rolling_forecast_df = pd.DataFrame()
          for num, (split_key, split_value) in enumerate(
              rolling_evaluation.items()
          ):
              forecast = split_value["pipeline_result"].forecast
              # Subsets forecast_horizon rows from the end of forecast dataframe
              forecast_df = forecast.df.iloc[
                  -forecast.forecast_horizon :
              ]
              forecast_df.insert(
                  0, "train_end_date", forecast.train_end_date
              )
              forecast_df.insert(
                  1,
                  FORECAST_STEP_COL,
                  np.arange(forecast.forecast_horizon) + 1,
              )
              forecast_df.insert(2, "split_num", num)
              rolling_forecast_df = pd.concat(
                  [rolling_forecast_df, forecast_df], axis=0
              )
          rolling_forecast_df = rolling_forecast_df.reset_index(
              drop=True
          )
          self.result[config_name][
              "rolling_forecast_df"
          ] = rolling_forecast_df
  
          # Merges the forecasts of individual config
          # Augments prediction columns with config name
          pred_cols = [PREDICTED_COL]
          if PREDICTED_LOWER_COL in rolling_forecast_df.columns:
              pred_cols.append(PREDICTED_LOWER_COL)
          if PREDICTED_UPPER_COL in rolling_forecast_df.columns:
              pred_cols.append(PREDICTED_UPPER_COL)
          mapper = {col: f"{config_name}_{col}" for col in pred_cols}
          if merged_df.empty:
              temp_df = rolling_forecast_df.rename(columns=mapper)
          else:
              temp_df = rolling_forecast_df[pred_cols].rename(
                  columns=mapper
              )
  
          merged_df = pd.concat([merged_df, temp_df], axis=1)
  
      self.forecasts = merged_df.reset_index(drop=True)
  
imports: from typing import Dict
  from typing import List
  import numpy
  import pandas
  import plotly.graph_objects
  from plotly.colors import DEFAULT_PLOTLY_COLORS
  from tqdm.autonotebook import tqdm
  from greykite.common.constants import ACTUAL_COL
  from greykite.common.constants import PREDICTED_COL
  from greykite.common.constants import PREDICTED_LOWER_COL
  from greykite.common.constants import PREDICTED_UPPER_COL
  from greykite.common.constants import TIME_COL
  from greykite.common.constants import VALUE_COL
  from greykite.common.evaluation import EvaluationMetricEnum
  from greykite.common.evaluation import add_finite_filter_to_scorer
  from greykite.common.logging import LoggingLevelEnum
  from greykite.common.logging import log_message
  from greykite.common.python_utils import get_pattern_cols
  from greykite.common.viz.timeseries_plotting import plot_multivariate
  from greykite.common.viz.timeseries_plotting import plot_multivariate_grouped
  from greykite.framework.benchmark.benchmark_class_helper import forecast_pipeline_rolling_evaluation
  from greykite.framework.constants import FORECAST_STEP_COL
  from greykite.framework.templates.autogen.forecast_config import ForecastConfig
  from greykite.framework.templates.forecaster import Forecaster
  from greykite.sklearn.cross_validation import RollingTimeSeriesSplit
label_desc: Use image node_id 4 for calling the BenchmarkForecastConfig obj's underlying member method code with example usage: obj.extract_forecasts() without return types