docs: def _univariate_handler(df, cols, stat=None, w=None, inplace=True,
                          pvalue = 'sim', outvals = None, swapname='', **kwargs):
      """
      Compute a univariate descriptive statistic `stat` over columns `cols` in
      `df`.
  
      Parameters
      ----------
      df          : pandas.DataFrame
                    the dataframe containing columns to compute the descriptive
                    statistics
      cols        : string or list of strings
                    one or more names of columns in `df` to use to compute
                    exploratory descriptive statistics.
      stat        : callable
                    a function that takes data as a first argument and any number
                    of configuration keyword arguments and returns an object
                    encapsulating the exploratory statistic results
      w           : pysal.weights.W
                    the spatial weights object corresponding to the dataframe
      inplace     : bool
                    a flag denoting whether to add the statistic to the dataframe
                    in memory, or to construct a copy of the dataframe and append
                    the results to the copy
      pvalue      : string
                    the name of the pvalue on the results object wanted
      outvals     : list of strings
                    names of attributes of the dataframe to attempt to flatten
                    into a column
      swapname    : string
                    suffix to replace generic identifier with. Each caller of this
                    function should set this to a unique column suffix
      **kwargs    : optional keyword arguments
                    options that are passed directly to the statistic
      """
      ### Preprocess
      if not inplace:
          new_df = df.copy()
          _univariate_handler(new_df, cols, stat=stat, w=w, pvalue=pvalue,
                                     inplace=True, outvals=outvals,
                                     swapname=swapname, **kwargs)
          return new_df
      if w is None:
          for name in df._metadata:
              this_obj = df.__dict__.get(name)
              if isinstance(this_obj, W):
                  w = this_obj
      if w is None:
          raise Exception('Weights not provided and no weights attached to frame!'
                              ' Please provide a weight or attach a weight to the'
                              ' dataframe')
      ### Prep indexes
      if outvals is None:
          outvals = []
      outvals.insert(0,'_statistic')
      if pvalue.lower() in ['all', 'both', '*']:
          raise NotImplementedError("If you want more than one type of PValue,add"
                                    " the targeted pvalue type to outvals. For example:"
                                    " Geary(df, cols=['HOVAL'], w=w, outvals=['p_z_sim', "
                                    "'p_rand']")
      # this is nontrivial, since we
      # can't know which p_value types are on the object without computing it.
      # This is because we don't flag them with @properties, so they're just
      # arbitrarily assigned post-facto. One solution might be to post-process the
      # objects, determine which pvalue types are available, and then grab them
      # all if needed.
  
      if pvalue is not '':
          outvals.append('p_'+pvalue.lower())
      if isinstance(cols, str):
          cols = [cols]
  
      ### Make closure around weights & apply columnwise
      def column_stat(column):
          return stat(column.values, w=w, **kwargs)
      stat_objs = df[cols].apply(column_stat)
  
      ### Assign into dataframe
      for col in cols:
          stat_obj = stat_objs[col]
          y = kwargs.get('y')
          if y is not None:
              col += '-' + y.name
          outcols = ['_'.join((col, val)) for val in outvals]
          for colname, attname in zip(outcols, outvals):
              df[colname] = stat_obj.__getattribute__(attname)
      if swapname is not '':
          df.columns = [_swap_ending(col, swapname) if col.endswith('_statistic') else col
                        for col in df.columns]