class_docstr: Create a MultipleFeatureDescriptors object.
  
  Create a list of features from **all** combinations of the given parameter
  lists. Total number of created `FeatureDescriptor`s will be:
  
      len(func_inputs)*len(functions)*len(windows)*len(strides).
  
  Parameters
  ----------
  functions : Union[FuncWrapper, Callable, List[Union[FuncWrapper, Callable]]]
      The functions, can be either of both types (even in a single array).
  series_names : Union[str, Tuple[str, ...], List[str], List[Tuple[str, ...]]]
      The names of the series on which the feature function should be applied.
  
      * If `series_names` is a (list of) string (or tuple of a single string),
        then each `function` should require just one series as input.
      * If `series_names` is a (list of) tuple of strings, then each `function` should
        require `len(tuple)` series as input.
  
      A `list` implies that multiple multiple series (combinations) will be used to
      extract features from; 
  
      * If `series_names` is a string or a tuple of strings, then `function` will
        be called only once for the series of this argument.
      * If `series_names` is a list of either strings or tuple of strings, then
        `function` will be called for each entry of this list.
  
      .. Note::
          when passing a list as `series_names`, all items in this list should
          have the same type, i.e, either 
  
          * all a str
          * or, all a tuple _with same length_.
  
          And perfectly match the func-input size.
  
  windows : Union[float, str, pd.Timedelta, List[Union[float, str, pd.Timedelta]]]
      All the window sizes.
  strides : Union[float, str, pd.Timedelta, None, List[Union[float, str, pd.Timedelta]]], optional
      All the strides. By default None.
  
  Note
  ----
  The `windows` and `strides` argument should be either both numeric or
  ``pd.Timedelta`` (depending on de index datatype) - when `strides` is not None.
code: def __init__(
      self,
      functions: Union[
          FuncWrapper, Callable, List[Union[FuncWrapper, Callable]]
      ],
      series_names: Union[
          str, Tuple[str, ...], List[str], List[Tuple[str, ...]]
      ],
      windows: Optional[
          Union[
              float,
              str,
              pd.Timedelta,
              List[Union[float, str, pd.Timedelta]],
          ]
      ] = None,
      strides: Optional[
          Union[
              float,
              str,
              pd.Timedelta,
              List[Union[float, str, pd.Timedelta]],
          ]
      ] = None,
  ):
      # Cast functions to FuncWrapper, this avoids creating multiple
      # FuncWrapper objects for the same function in the FeatureDescriptor
      def to_func_wrapper(f: Callable):
          return f if isinstance(f, FuncWrapper) else FuncWrapper(f)
  
      functions = [to_func_wrapper(f) for f in to_list(functions)]
      # Convert the series names to list of tuples
      series_names = [
          to_tuple(names) for names in to_list(series_names)
      ]
      # Assert that function inputs (series) all have the same length
      assert all(
          len(series_names[0]) == len(series_name_tuple)
          for series_name_tuple in series_names
      )
      # Convert the other types to list
      windows = to_list(windows)
  
      self.feature_descriptions: List[FeatureDescriptor] = []
      # Iterate over all combinations
      combinations = [functions, series_names, windows]
      for function, series_name, window in itertools.product(
          *combinations
      ):
          self.feature_descriptions.append(
              FeatureDescriptor(function, series_name, window, strides)
          )
  
file_path: tsflex/tsflex/features/feature.py
imports: import itertools
  from typing import Callable, List, Optional, Tuple, Union
  import pandas
  from ..utils.attribute_parsing import AttributeParser, DataType
  from ..utils.classes import FrozenClass
  from ..utils.data import to_list, to_tuple
  from ..utils.time import parse_time_arg
  from .function_wrapper import FuncWrapper
label_desc: Use image node_id 1 to create a new MultipleFeatureDescriptors object  with example: obj = MultipleFeatureDescriptors(functions, series_names, windows, strides)