docs: def posthoc_nemenyi(a, val_col=None, group_col=None,  dist='chi', sort=True):
  
      '''Post hoc pairwise test for multiple comparisons of mean rank sums
      (Nemenyi's test). May be used after Kruskal-Wallis one-way analysis of
      variance by ranks to do pairwise comparisons [1]_.
  
      Parameters
      ----------
      a : array_like or pandas DataFrame object
          An array, any object exposing the array interface or a pandas
          DataFrame. Array must be two-dimensional. Second dimension may vary,
          i.e. groups may have different lengths.
  
      val_col : str, optional
          Name of a DataFrame column that contains dependent variable values (test
          or response variable). Values should have a non-nominal scale. Must be
          specified if `a` is a pandas DataFrame object.
  
      group_col : str, optional
          Name of a DataFrame column that contains independent variable values
          (grouping or predictor variable). Values should have a nominal scale
          (categorical). Must be specified if `a` is a pandas DataFrame object.
  
      dist : str, optional
          Method for determining the p value. The default distribution is "chi"
          (chi-squared), else "tukey" (studentized range).
  
      sort : bool, optional
          Specifies whether to sort DataFrame by group_col or not. Recommended
          unless you sort your data manually.
  
      Returns
      -------
      result : pandas DataFrame
          P values.
  
      Notes
      -----
      A tie correction will be employed according to Glantz (2012).
  
      References
      ----------
      .. [1] Lothar Sachs (1997), Angewandte Statistik. Berlin: Springer.
          Pages: 395-397, 662-664.
  
      Examples
      --------
      >>> x = [[1,2,3,5,1], [12,31,54, np.nan], [10,12,6,74,11]]
      >>> sp.posthoc_nemenyi(x)
      '''
  
      def compare_stats_chi(i, j):
          diff = np.abs(x_ranks_avg.loc[i] - x_ranks_avg.loc[j])
          A = n * (n + 1.) / 12.
          B = (1. / x_lens.loc[i] + 1. / x_lens.loc[j])
          chi = diff ** 2. / (A * B)
          return chi
  
      def compare_stats_tukey(i, j):
          diff = np.abs(x_ranks_avg.loc[i] - x_ranks_avg.loc[j])
          B = (1. / x_lens.loc[i] + 1. / x_lens.loc[j])
          q = diff / np.sqrt((n * (n + 1.) / 12.) * B)
          return q
  
      x, _val_col, _group_col = __convert_to_df(a, val_col, group_col)
  
      if not sort:
          x[_group_col] = Categorical(x[_group_col], categories=x[_group_col].unique(), ordered=True)
  
      x.sort_values(by=[_group_col, _val_col], ascending=True, inplace=True)
      n = len(x.index)
      x_groups_unique = np.unique(x[_group_col])
      x_len = x_groups_unique.size
      x_lens = x.groupby(_group_col)[_val_col].count()
  
      x['ranks'] = x[_val_col].rank()
      x_ranks_avg = x.groupby(_group_col)['ranks'].mean()
  
      # ties
      vals = x.groupby('ranks').count()[_val_col].values
      tie_sum = np.sum(vals[vals != 1] ** 3 - vals[vals != 1])
      tie_sum = 0 if not tie_sum else tie_sum
      x_ties = np.min([1., 1. - tie_sum / (n ** 3. - n)])
  
      vs = np.zeros((x_len, x_len))
      combs = it.combinations(range(x_len), 2)
  
      tri_upper = np.triu_indices(vs.shape[0], 1)
      tri_lower = np.tril_indices(vs.shape[0], -1)
      vs[:,:] = 0
  
      if dist == 'chi':
          for i,j in combs:
              vs[i, j] = compare_stats_chi(x_groups_unique[i], x_groups_unique[j]) / x_ties
  
          vs[tri_upper] = ss.chi2.sf(vs[tri_upper], x_len - 1)
  
      elif dist == 'tukey':
          for i,j in combs:
              vs[i, j] = compare_stats_tukey(x_groups_unique[i], x_groups_unique[j]) * np.sqrt(2.)
  
          vs[tri_upper] = psturng(vs[tri_upper], x_len, np.inf)
  
      vs[tri_lower] = vs.T[tri_lower]
      np.fill_diagonal(vs, -1)
  
      return DataFrame(vs, index=x_groups_unique, columns=x_groups_unique)