docs: def reduce(self, func, dim=None, axis=None,
                 keep_attrs=None, allow_lazy=False, **kwargs):
          """Reduce this array by applying `func` along some dimension(s).
  
          Parameters
          ----------
          func : function
              Function which can be called in the form
              `func(x, axis=axis, **kwargs)` to return the result of reducing an
              np.ndarray over an integer valued axis.
          dim : str or sequence of str, optional
              Dimension(s) over which to apply `func`.
          axis : int or sequence of int, optional
              Axis(es) over which to apply `func`. Only one of the 'dim'
              and 'axis' arguments can be supplied. If neither are supplied, then
              the reduction is calculated over the flattened array (by calling
              `func(x)` without an axis argument).
          keep_attrs : bool, optional
              If True, the variable's attributes (`attrs`) will be copied from
              the original object to the new one.  If False (default), the new
              object will be returned without attributes.
          **kwargs : dict
              Additional keyword arguments passed on to `func`.
  
          Returns
          -------
          reduced : Array
              Array with summarized data and the indicated dimension(s)
              removed.
          """
          if dim is common.ALL_DIMS:
              dim = None
          if dim is not None and axis is not None:
              raise ValueError("cannot supply both 'axis' and 'dim' arguments")
  
          if dim is not None:
              axis = self.get_axis_num(dim)
          input_data = self.data if allow_lazy else self.values
          if axis is not None:
              data = func(input_data, axis=axis, **kwargs)
          else:
              data = func(input_data, **kwargs)
  
          if getattr(data, 'shape', ()) == self.shape:
              dims = self.dims
          else:
              removed_axes = (range(self.ndim) if axis is None
                              else np.atleast_1d(axis) % self.ndim)
              dims = [adim for n, adim in enumerate(self.dims)
                      if n not in removed_axes]
  
          if keep_attrs is None:
              keep_attrs = _get_keep_attrs(default=False)
          attrs = self._attrs if keep_attrs else None
  
          return Variable(dims, data, attrs=attrs)