code: def _parallel_apply(
      iterator: Iterator[Tuple],
      fn: Callable,
      n_jobs: int,
      fn_args,
      fn_kwargs,
  ) -> List:
      """
      Utility function that parallelise the execution of a function over an Iterator
  
      Parameters
      ----------
      iterator (Iterator[Tuple])
          Iterator which returns tuples of input value to feed to fn. Constant `args` and `kwargs` should passed through
          `fn_args` and  `fn_kwargs` respectively.
      fn (Callable)
          The function to be parallelized.
      n_jobs (int)
          The number of jobs to run in parallel. Defaults to `1` (sequential). Setting the parameter to `-1` means using
          all the available processors.
          Note: for a small amount of data, the parallelisation overhead could end up increasing the total
          required amount of time.
      fn_args
          Additional arguments for each `fn()` call
      fn_kwargs
          Additional keyword arguments for each `fn()` call
  
      """
  
      returned_data = Parallel(n_jobs=n_jobs)(
          delayed(fn)(*sample, *fn_args, **fn_kwargs)
          for sample in iterator
      )
      return returned_data
  
imports: from enum import Enum
  from functools import wraps
  from inspect import Parameter, getcallargs, signature
  from typing import Callable, Iterator, List, Optional, Sequence, Tuple, TypeVar, Union
  import pandas
  from joblib import Parallel, delayed
  from tqdm import tqdm
  from tqdm.notebook import tqdm
  from darts import TimeSeries
  from darts.logging import get_logger, raise_if_not, raise_log
  from darts.utils.timeseries_generation import generate_index
label_desc: Use image node_id 4 for calling a global function with example usage: _parallel_apply(iterator, fn, n_jobs, fn_args, fn_kwargs) and returns: returned_data