code: def reduction(input_type, output_type):
          
          return udf._grouped(
              input_type,
              output_type,
              base_class=ops.Reduction,
              output_type_method=operator.attrgetter('scalar_type'),
          )
docs: Define a user-defined reduction function that takes N pandas Series
          or scalar values as inputs and produces one row of output.
  
          Parameters
          ----------
          input_type : List[ibis.expr.datatypes.DataType]
              A list of the types found in :mod:`~ibis.expr.datatypes`. The
              length of this list must match the number of arguments to the
              function. Variadic arguments are not yet supported.
          output_type : ibis.expr.datatypes.DataType
              The return type of the function.
  
          Examples
          --------
          >>> import ibis
          >>> import ibis.expr.datatypes as dt
          >>> from ibis.pandas.udf import udf
          >>> @udf.reduction(input_type=[dt.string], output_type=dt.int64)
          ... def my_string_length_agg(series, **kwargs):
          ...     return (series.str.len() * 2).sum()