class_docstr: Complements the event system by providing aggregation functionality. How the events are aggregated
  is specified by the event interface decorators (see event_decorators.py).
  
  Note that the statistics calculation for episode aggregators will automatically be
  triggered on every `increment_log_step()` call.
class_docstr_tok: ["Complements","the","event","system","by","providing","aggregation","functionality",".","How","the","events","are","aggregated","is","specified","by","the","event","interface","decorators","(","see","event_decorators.py",")",".","Note","that","the","statistics","calculation","for","episode","aggregators","will","automatically","be","triggered","on","every","`","increment_log_step","(",")","`","call","."]
docstr: Execute the given reduce function.
  
  Note that the input and output of the reduce function is not limited to a (lists of) attribute dictionaries
  as defined in :attr:`maze.core.events.event_record.EventRecord.attributes <EventRecord.attributes>`,
  but can be any custom data structure.
docstr_tok: ["Execute","the","given","reduce","function",".","Note","that","the","input","and","output","of","the","reduce","function","is","not","limited","to","a","(","lists","of",")","attribute","dictionaries","as","defined","in",":","attr",":","`","maze.core.events.event_record.EventRecord.attributes","<","EventRecord.attributes",">","`",",","but","can","be","any","custom","data","structure","."]
code: def _reduce(
      cls, reduce_function: Callable, values: List[Any], event: Callable
  ) -> Any:
      """Execute the given reduce function.
  
      Note that the input and output of the reduce function is not limited to a (lists of) attribute dictionaries
      as defined in :attr:`maze.core.events.event_record.EventRecord.attributes <EventRecord.attributes>`,
      but can be any custom data structure.
      """
      # special case: no aggregation
      if reduce_function is None:
          if len(values) > 1:
              raise AssertionError(
                  "event with aggregation skip operation 'None' is dispatched "
                  "more than once per step: {} ".format(event)
              )
  
          # get the first and only value
          first_value = values[0]
          if type(first_value) is not dict:
              return first_value
  
          # if there is more than one attribute defined for the event, return the entire dict
          if len(first_value) > 1:
              return tuple(first_value.values())
  
          return next(iter(first_value.values()))
  
      # execute the actual aggregation operation
      return reduce_function(values)
  
imports: from abc import ABC, abstractmethod
  from collections import defaultdict
  from enum import Enum
  from typing import Union, Callable, Dict, Optional, NamedTuple, List, Type, TypeVar, Tuple, Any
  import numpy
  from maze.core.events.event_record import EventRecord
  from maze.core.events.event_topic_factory import event_topic_factory
label_desc: Use image node_id 10 for calling the LogStatsAggregator obj's underlying member method code with example usage: obj._reduce(cls, reduce_function, values, event) and returns: reduce_function, next, first_value, tuple