docstr: Save NeuralForecast core class.
  
  `core.NeuralForecast`'s method to save current status of models, dataset, and configuration.
  Note that by default the `models` are not saving training checkpoints to save disk memory,
  to get them change the individual model `**trainer_kwargs` to include `enable_checkpointing=True`.
  
  Parameters
  ----------
  path : str
      Directory to save current status.
  model_index : list, optional (default=None)
      List to specify which models from list of self.models to save.
  save_dataset : bool (default=True)
      Whether to save dataset or not.
  overwrite : bool (default=False)
      Whether to overwrite files or not.
docstr_tok: ["Save","NeuralForecast","core","class",".","`","core.NeuralForecast","`","'s","method","to","save","current","status","of","models",",","dataset",",","and","configuration",".","Note","that","by","default","the","`","models","`","are","not","saving","training","checkpoints","to","save","disk","memory",",","to","get","them","change","the","individual","model","`","*","*","trainer_kwargs","`","to","include","`","enable_checkpointing=True","`",".","Parameters","--","--","--","--","--","path",":","str","Directory","to","save","current","status",".","model_index",":","list",",","optional","(","default=None",")","List","to","specify","which","models","from","list","of","self.models","to","save",".","save_dataset",":","bool","(","default=True",")","Whether","to","save","dataset","or","not",".","overwrite",":","bool","(","default=False",")","Whether","to","overwrite","files","or","not","."]
code: def save(
      self,
      path: str,
      model_index: Optional[List] = None,
      save_dataset: bool = True,
      overwrite: bool = False,
  ):
      """Save NeuralForecast core class.
  
      `core.NeuralForecast`'s method to save current status of models, dataset, and configuration.
      Note that by default the `models` are not saving training checkpoints to save disk memory,
      to get them change the individual model `**trainer_kwargs` to include `enable_checkpointing=True`.
  
      Parameters
      ----------
      path : str
          Directory to save current status.
      model_index : list, optional (default=None)
          List to specify which models from list of self.models to save.
      save_dataset : bool (default=True)
          Whether to save dataset or not.
      overwrite : bool (default=False)
          Whether to overwrite files or not.
      """
      # Standarize path without '/'
      if path[-1] == "/":
          path = path[:-1]
  
      # Model index list
      if model_index is None:
          model_index = list(range(len(self.models)))
  
      # Create directory if not exists
      os.makedirs(path, exist_ok=True)
  
      # Check if directory is empty to protect overwriting files
      dir = os.listdir(path)
  
      # Checking if the list is empty or not
      if (len(dir) > 0) and (not overwrite):
          raise Exception(
              "Directory is not empty. Set `overwrite=True` to overwrite files."
          )
  
      # Save models
      count_names = {"model": 0}
      for i, model in enumerate(self.models):
          # Skip model if not in list
          if i not in model_index:
              continue
  
          model_name = repr(model).lower().replace("_", "")
          count_names[model_name] = count_names.get(model_name, -1) + 1
          model.save(
              f"{path}/{model_name}_{count_names[model_name]}.ckpt"
          )
  
      # Save dataset
      if (save_dataset) and (hasattr(self, "dataset")):
          with open(f"{path}/dataset.pkl", "wb") as f:
              pickle.dump(self.dataset, f)
      elif save_dataset:
          raise Exception(
              "You need to have a stored dataset to save it, \
                               set `save_dataset=False` to skip saving dataset."
          )
  
      # Save configuration and parameters
      config_dict = {
          "h": self.h,
          "freq": self.freq,
          "uids": self.uids,
          "last_dates": self.last_dates,
          "ds": self.ds,
          "sort_df": self.sort_df,
          "_fitted": self._fitted,
          "local_scaler_type": self.local_scaler_type,
          "scalers_": self.scalers_,
          "id_col": self.id_col,
          "time_col": self.time_col,
          "target_col": self.target_col,
      }
  
      with open(f"{path}/configuration.pkl", "wb") as f:
          pickle.dump(config_dict, f)
  
imports: import os
  import pickle
  import warnings
  from copy import deepcopy
  from itertools import chain
  from typing import Any, Dict, List, Optional, Union
  import numpy
  import pandas
  import torch
  import utilsforecast.processing
  from utilsforecast.compat import DataFrame, Series, pl_DataFrame, pl_Series
  from utilsforecast.grouped_array import GroupedArray
  from utilsforecast.target_transforms import BaseTargetTransform, LocalBoxCox, LocalMinMaxScaler, LocalRobustScaler, LocalStandardScaler
  from utilsforecast.validation import validate_freq
  from .tsdataset import TimeSeriesDataset
  from neuralforecast.models import GRU, LSTM, RNN, TCN, DeepAR, DilatedRNN, MLP, NHITS, NBEATS, NBEATSx, TFT, VanillaTransformer, Informer, Autoformer, FEDformer, StemGNN, PatchTST, TimesNet
label_desc: Use image node_id 15 for calling the NeuralForecast obj's underlying member method code with example usage: obj.save(path, model_index, save_dataset, overwrite) without return types