docs: def posthoc_tamhane(a, val_col=None, group_col=None, welch=True, sort=False):
  
      '''Tamhane's T2 all-pairs comparison test for normally distributed data with
      unequal variances. Tamhane's T2 test can be performed for all-pairs
      comparisons in an one-factorial layout with normally distributed residuals
      but unequal groups variances. A total of m = k(k-1)/2 hypotheses can be
      tested. The null hypothesis is tested in the two-tailed test against the
      alternative hypothesis [1]_.
  
      Parameters
      ----------
      a : array_like or pandas DataFrame object
          An array, any object exposing the array interface or a pandas
          DataFrame.
  
      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.
  
      welch : bool, optional
          If True, use Welch's approximate solution for calculating the degree of
          freedom. T2 test uses the usual df = N - 2 approximation.
  
      sort : bool, optional
          If True, sort data by block and group columns.
  
      Returns
      -------
      result : pandas DataFrame
          P values.
  
      Notes
      -----
      The p values are computed from the t-distribution and adjusted according to
      Dunn-Sidak.
  
      References
      ----------
      .. [1] A.C. Tamhane (1979), A Comparison of Procedures for Multiple Comparisons of
          Means with Unequal Variances. Journal of the American Statistical Association,
          74, 471-480.
  
      Examples
      --------
      >>> import scikit_posthocs as sp
      >>> import pandas as pd
      >>> x = pd.DataFrame({"a": [1,2,3,5,1], "b": [12,31,54,62,12], "c": [10,12,6,74,11]})
      >>> x = x.melt(var_name='groups', value_name='values')
      >>> sp.posthoc_tamhane(x, val_col='values', group_col='groups')
  
      '''
  
      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], ascending=True, inplace=True)
      groups = x[_group_col].unique()
  
      x_grouped = x.groupby(_group_col)[_val_col]
  
      ni = x_grouped.count()
      n = ni.sum()
      xi = x_grouped.mean()
      si = x_grouped.var()
      sin = 1. / (n - groups.size) * np.sum(si * (ni - 1))
  
      def compare(i, j):
          dif = xi[i] - xi[j]
          A = si[i] / ni[i] + si[j] / ni[j]
          t_val = dif / np.sqrt(A)
          if welch:
              df = A ** 2. / (si[i] ** 2. / (ni[i] ** 2. * (ni[i] - 1.)) + si[j] ** 2. / (ni[j] ** 2. * (ni[j] - 1.)))
          else:
              ## checks according to Tamhane (1979, p. 474)
              ok1 = (9./10. <= ni[i]/ni[j]) and (ni[i]/ni[j] <= 10./9.)
              ok2 = (9./10. <= (s2i[i] / ni[i]) / (s2i[j] / ni[j])) and ((s2i[i] / ni[i]) / (s2i[j] / ni[j]) <= 10./9.)
              ok3 = (4./5. <= ni[i]/ni[j]) and (ni[i]/ni[j] <= 5./4.) and (1./2. <= (s2i[i] / ni[i]) / (s2i[j] / ni[j])) and ((s2i[i] / ni[i]) / (s2i[j] / ni[j]) <= 2.)
              ok4 = (2./3. <= ni[i]/ni[j]) and (ni[i]/ni[j] <= 3./2.) and (3./4. <= (s2i[i] / ni[i]) / (s2i[j] / ni[j])) and ((s2i[i] / ni[i]) / (s2i[j] / ni[j]) <= 4./3.)
              OK = any(ok1, ok2, ok3, ok4)
              if not OK:
                  print("Sample sizes or standard errors are not balanced. T2 test is recommended.")
              df = ni[i] + ni[j] - 2.
          p_val = 2. * ss.t.sf(np.abs(t_val), df=df)
          return p_val
  
      vs = np.zeros((groups.size, groups.size), dtype=np.float)
      tri_upper = np.triu_indices(vs.shape[0], 1)
      tri_lower = np.tril_indices(vs.shape[0], -1)
      vs[:,:] = 0
  
      combs = it.combinations(range(groups.size), 2)
  
      for i,j in combs:
          vs[i, j] = compare(groups[i], groups[j])
  
      vs[tri_upper] = 1. - (1. - vs[tri_upper]) ** groups.size
      vs[tri_lower] = vs.T[tri_lower]
      vs[vs > 1] = 1
  
      np.fill_diagonal(vs, -1)
      return DataFrame(vs, index=groups, columns=groups)