code: def compute_metrics(fcst_df, metric_name=None, ts_id_colnames=None):
      """
      Calculate metrics per grain.
  
      :param fcst_df: forecast data frame. Must contain 2 columns: 'actual_level' and 'predicted_level'
      :param metric_name: (optional) name of the metric to return
      :param ts_id_colnames: (optional) list of grain column names
      :return: dictionary of summary table for all tests and final decision on stationary vs nonstaionary
      """
      if ts_id_colnames is None:
          ts_id_colnames = []
      if len(ts_id_colnames) == 0:
          ts_id_colnames = ["TS_ID"]
          fcst_df[ts_id_colnames[0]] = "dummy"
      metrics_list = []
      for grain, df in fcst_df.groupby(ts_id_colnames):
          try:
              scores = scoring.score_regression(
                  y_test=df["actual_level"],
                  y_pred=df["predicted_level"],
                  metrics=list(constants.Metric.SCALAR_REGRESSION_SET),
              )
          except BaseException:
              msg = "{}: metrics calculation failed.".format(grain)
              print(msg)
              scores = {}
          one_grain_metrics_df = pd.DataFrame(
              list(scores.items()), columns=["metric_name", "metric"]
          ).sort_values(["metric_name"])
          one_grain_metrics_df.reset_index(inplace=True, drop=True)
          if len(ts_id_colnames) < 2:
              one_grain_metrics_df["grain"] = ts_id_colnames[0]
          else:
              one_grain_metrics_df["grain"] = "|".join(list(grain))
  
          metrics_list.append(one_grain_metrics_df)
      # collect into a data frame
      grain_metrics = pd.concat(metrics_list)
      if metric_name is not None:
          grain_metrics = grain_metrics.query(
              "metric_name == @metric_name"
          )
      return grain_metrics
  
file_path: MachineLearningNotebooks/how-to-use-azureml/automated-machine-learning/forecasting-recipes-univariate/helper_functions.py
imports: import pandas
  import statsmodels.tsa.stattools
  from arch import unitroot
  from azureml.automl.core.shared import constants
  from azureml.automl.runtime.shared.score import scoring
label_desc: Use image node_id 6 for calling a global function with example usage: compute_metrics(fcst_df, metric_name, ts_id_colnames) and returns: grain_metrics