def save_for_monitoring(predictions: pd.DataFrame, start_datetime: datetime):
    """Save predictions to GCS for monitoring.

    The predictions are saved as a parquet file in GCS.
    The predictions are saved in a bucket with the following structure:
    gs://<BUCKET_NAME>/predictions_monitoring.parquet

    The predictions are stored in a multiindex dataframe with the following indexes:
    - area: The area of the predictions, e.g. "DK1".
    - consumer_type: The consumer type of the predictions, e.g. "residential".
    - datetime_utc: The timestamp of the predictions, e.g. "2020-01-01 00:00:00" with a frequency of 1 hour.
    """

    bucket = utils.get_bucket()

    cached_predictions = utils.read_blob_from(
        bucket=bucket, blob_name=f"predictions_monitoring.parquet"
    )
    has_cached_predictions = cached_predictions is not None
    if has_cached_predictions is True:
        # Merge predictions with cached predictions.
        cached_predictions.index = cached_predictions.index.set_levels(
            pd.to_datetime(cached_predictions.index.levels[2], unit="h").to_period("H"),
            level=2,
        )

        merged_predictions = predictions.merge(
            cached_predictions,
            left_index=True,
            right_index=True,
            how="outer",
            suffixes=("_new", "_cached"),
        )
        new_predictions = merged_predictions.filter(regex=".*?_new")
        new_predictions.columns = new_predictions.columns.str.replace("_new", "")
        cached_predictions = merged_predictions.filter(regex=".*?_cached")
        cached_predictions.columns = cached_predictions.columns.str.replace(
            "_cached", ""
        )

        # NOTE: fillna() not working properly on multindex DataFrames. Got nasty bugs because of it.
        new_predictions.update(cached_predictions)
        predictions = new_predictions

    predictions = predictions.loc[
        predictions.index.get_level_values("datetime_utc")
        >= pd.Period(start_datetime, freq="H")
    ]
    predictions = predictions.dropna(subset=["energy_consumption"])

    utils.write_blob_to(
        bucket=bucket,
        blob_name=f"predictions_monitoring.parquet",
        data=predictions,
    )
    logger.info(f"Successfully cached predictions forecasted before {start_datetime}.")
Save predictions to GCS for monitoring.

    The predictions are saved as a parquet file in GCS.
    The predictions are saved in a bucket with the following structure:
    gs://<BUCKET_NAME>/predictions_monitoring.parquet

    The predictions are stored in a multiindex dataframe with the following indexes:
    - area: The area of the predictions, e.g. "DK1".
    - consumer_type: The consumer type of the predictions, e.g. "residential".
    - datetime_utc: The timestamp of the predictions, e.g. "2020-01-01 00:00:00" with a frequency of 1 hour.
    
batch-prediction-pipeline/batch_prediction_pipeline/batch.py