class_docstr: A FeatureDescriptor object, containing all feature information.
  
  Parameters
  ----------
  function : Union[FuncWrapper, Callable]
      The function that calculates the feature(s).
      The prototype of the function should match: 
  
  
          function(*series: Union[np.array, pd.Series])
              -> Union[Any, List[Any]]
  
      Note that when the input type is ``pd.Series``, the function should be wrapped
        in a `FuncWrapper` with `input_type` = ``pd.Series``.
  
  series_name : Union[str, Tuple[str, ...]]
      The names of the series on which the feature function should be applied.
      This argument should match the `function` its input; 
  
      * If `series_name` is a string (or tuple of a single string), then
          `function` should require just one series as input.
      * If `series_name` is a tuple of strings, then `function` should
          require `len(tuple)` series as input **and in exactly the same order**
  
  window : Union[float, str, pd.Timedelta], optional
      The window size. By default None. This argument supports multiple types: 
  
      * If None, the `segment_start_idxs` and `segment_end_idxs` will need to be
        passed.
      * If the type is an `float` or an `int`, its value represents the series
          - its window **range** when a **non time-indexed** series is passed.
          - its window in **number of samples**, when a **time-indexed** series is
            passed (must then be and `int`)
      * If the window's type is a `pd.Timedelta`, the window size represents
        the window-time-range. The passed data **must have a time-index**.
      * If a `str`, it must represents a window-time-range-string. The **passed data
        must have a time-index**.
      .. Note::
          - When the `segment_start_idxs` and `segment_end_idxs` are both passed to
            the `FeatureCollection.calculate` method, this window argument is ignored.
            Note that this is the only case when it is allowed to pass None for the
            window argument.
          - When the window argument is None, than the stride argument should be None
            as well (as it makes no sense to pass a stride value when the window is
            None).
  
  stride : Union[float, str, pd.Timedelta, List[Union[float, str, pd.Timedelta]]], optional
      The stride size(s). By default None. This argument supports multiple types: 
  
      * If None, the stride will need to be passed to `FeatureCollection.calculate`.
      * If the type is an `float` or an `int`, its value represents the series
          - its stride **range** when a **non time-indexed** series is passed.
          - the stride in **number of samples**, when a **time-indexed** series
            is passed (must then be and `int`)
      * If the stride's type is a `pd.Timedelta`, the stride size represents
        the stride-time delta. The passed data **must have a time-index**.
      * If a `str`, it must represent a stride-time-delta-string. The **passed data
        must have a time-index**. 
  
      * If a `List[Union[float, str, pd.Timedelta]]`, then the set intersection,of the
        strides will be used (e.g., stride=[2,3] -> index: 0, 2, 3, 4, 6, 8, 9, ...)
      .. Note::
          - The stride argument of `FeatureCollection.calculate` takes precedence over
            this value when set (i.e., not None value for `stride` passed to the
            `calculate` method).
          - The stride argument should be None when the window argument is None (as it
            makes no sense to pass a stride value when the window is None).
  
  .. Note::
      As described above, the `window-stride` argument can be sample-based (when using
      time-index series and int based arguments), but we
      do **not encourage** using this for `time-indexed` sequences. As we make the
      implicit assumption that the time-based data is sampled at a fixed frequency
      So only, if you're 100% sure that this is correct, you can safely use such
      arguments.
  
  Notes
  -----
  * The `window` and `stride` argument should be either **both** numeric or
    ``pd.Timedelta`` (depending on de index datatype) - when `stride` is not None.
  * For each `function` - `input`(-series) - `window` - stride combination, one needs
    to create a distinct `FeatureDescriptor`. Hence it is more convenient to
    create a `MultipleFeatureDescriptors` when `function` - `window` - `stride`
    **combinations** should be applied on various input-series (combinations).
  * When `function` takes **multiple series** (i.e., arguments) as **input**, these
    are joined (based on the index) before applying the function. If the indexes of
    these series are not exactly the same, it might occur that not all series have
    exactly the same length! Hence,  make sure that the `function` can deal with
    this!
  * For more information about the str-based time args, look into:
    [pandas time delta](https://pandas.pydata.org/pandas-docs/stable/user_guide/timedeltas.html#parsing){:target="_blank"}
  
  Raises
  ------
  TypeError
      * Raised when the `function` is not an instance of Callable or FuncWrapper.
      * Raised when `window` and `stride` are not of exactly the same type (when
        `stride` is not None).
  
  See Also
  --------
  StridedRolling: As the window-stride sequence conversion takes place there.
docstr: Return the number of output features of this feature descriptor.
  
  Returns
  -------
  int
      Number of output features.
docstr_tok: ["Return","the","number","of","output","features","of","this","feature","descriptor",".","Returns","--","--","--","-","int","Number","of","output","features","."]
code: def get_nb_output_features(self) -> int:
      """Return the number of output features of this feature descriptor.
  
      Returns
      -------
      int
          Number of output features.
  
      """
      return len(self.function.output_names)
  
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 3 for calling the FeatureDescriptor obj's underlying member method code with example usage: obj.get_nb_output_features() and returns: len