class_docstr: Aggregator instance which uses the passed aggregation func.
  
  !!! warning
  
      The user has total control which `aggregation_func` is passed to this method,
      hence the user should be careful to not make copies of the data, nor write to
      the data. Furthermore, the user should beware of performance issues when
      using more complex aggregation functions.
  
  !!! warning "Attention"
  
      The user has total control which `aggregation_func` is passed to this method,
      hence it is the users' responsibility to handle categorical and bool-based
      data types.
class_docstr_tok: ["Aggregator","instance","which","uses","the","passed","aggregation","func",".","!","!","!","warning","The","user","has","total","control","which","`","aggregation_func","`","is","passed","to","this","method",",","hence","the","user","should","be","careful","to","not","make","copies","of","the","data",",","nor","write","to","the","data",".","Furthermore",",","the","user","should","beware","of","performance","issues","when","using","more","complex","aggregation","functions",".","!","!","!","warning","``","Attention","''","The","user","has","total","control","which","`","aggregation_func","`","is","passed","to","this","method",",","hence","it","is","the","users","'","responsibility","to","handle","categorical","and","bool-based","data","types","."]
docstr: Aggregate the data using the object's aggregation function.
  
  Parameters
  ----------
  x: np.ndarray | None
      The x-values of the data. Can be None if no x-values are available.
  y: np.ndarray
      The y-values of the data.
  n_out: int
      The number of output data points.
  **kwargs
      Additional keyword arguments, which are passed to the aggregation function.
  
  Returns
  -------
  Tuple[np.ndarray, np.ndarray]
      The aggregated x & y values.
      If `x` is None, then the indices of the first element of each bin is
      returned as x-values.
docstr_tok: ["Aggregate","the","data","using","the","object","'s","aggregation","function",".","Parameters","--","--","--","--","--","x",":","np.ndarray","|","None","The","x-values","of","the","data",".","Can","be","None","if","no","x-values","are","available",".","y",":","np.ndarray","The","y-values","of","the","data",".","n_out",":","int","The","number","of","output","data","points",".","*","*","kwargs","Additional","keyword","arguments",",","which","are","passed","to","the","aggregation","function",".","Returns","--","--","--","-","Tuple","[","np.ndarray",",","np.ndarray","]","The","aggregated","x","&","y","values",".","If","`","x","`","is","None",",","then","the","indices","of","the","first","element","of","each","bin","is","returned","as","x-values","."]
code: def _aggregate(
      self,
      x: np.ndarray | None,
      y: np.ndarray,
      n_out: int,
  ) -> Tuple[np.ndarray, np.ndarray]:
      """Aggregate the data using the object's aggregation function.
  
      Parameters
      ----------
      x: np.ndarray | None
          The x-values of the data. Can be None if no x-values are available.
      y: np.ndarray
          The y-values of the data.
      n_out: int
          The number of output data points.
      **kwargs
          Additional keyword arguments, which are passed to the aggregation function.
  
      Returns
      -------
      Tuple[np.ndarray, np.ndarray]
          The aggregated x & y values.
          If `x` is None, then the indices of the first element of each bin is
          returned as x-values.
  
      """
      # Create an index-estimation for real-time data
      # Add one to the index so it's pointed at the end of the window
      # Note: this can be adjusted to .5 to center the data
      # Multiply it with the group size to get the real index-position
      # TODO: add option to select start / middle / end as index
      if x is None:
          # equidistant index
          idxs = np.linspace(0, len(y), n_out + 1).astype(int)
      else:
          xdt = x.dtype
          if np.issubdtype(xdt, np.datetime64) or np.issubdtype(
              xdt, np.timedelta64
          ):
              x = x.view("int64")
          # Thanks to `linspace`, the data is evenly distributed over the index-range
          # The searchsorted function returns the index positions
          idxs = np.searchsorted(x, np.linspace(x[0], x[-1], n_out + 1))
  
      y_agg = np.array(
          [
              self.aggregation_func(y[t0:t1], **self.downsample_kwargs)
              for t0, t1 in zip(idxs[:-1], idxs[1:])
          ]
      )
  
      if x is not None:
          x_agg = x[idxs[:-1]]
      else:
          # x is None -> return the indices of the first element of each bin
          x_agg = idxs[:-1]
  
      return x_agg, y_agg
  
imports: from __future__ import annotations
  import math
  from typing import Tuple
  import numpy
  from tsdownsample import EveryNthDownsampler, LTTBDownsampler, MinMaxDownsampler, MinMaxLTTBDownsampler
  from ..aggregation.aggregation_interface import DataAggregator, DataPointSelector
label_desc: Use image node_id 2 for calling the FuncAggregator obj's underlying member method code with example usage: obj._aggregate(x, y, n_out) and returns: x_agg,  y_agg