code: def posthoc_conover(
      a: Union[list, np.ndarray, DataFrame],
      val_col: str = None,
      group_col: str = None,
      p_adjust: str = None,
      sort: bool = True,
  ) -> DataFrame:
      """Post hoc pairwise test for multiple comparisons of mean rank sums
      (Conover´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.
  
      p_adjust : str, optional
          Method for adjusting p values. See `statsmodels.sandbox.stats.multicomp`
          for details. Available methods are:
          'bonferroni' : one-step correction
          'sidak' : one-step correction
          'holm-sidak' : step-down method using Sidak adjustments
          'holm' : step-down method using Bonferroni adjustments
          'simes-hochberg' : step-up method  (independent)
          'hommel' : closed method based on Simes tests (non-negative)
          'fdr_bh' : Benjamini/Hochberg  (non-negative)
          'fdr_by' : Benjamini/Yekutieli (negative)
          'fdr_tsbh' : two stage fdr correction (non-negative)
          'fdr_tsbky' : two stage fdr correction (non-negative)
  
      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 are employed according to Conover [1]_.
  
      References
      ----------
      .. [1] W. J. Conover and R. L. Iman (1979), On multiple-comparisons
          procedures, Tech. Rep. LA-7677-MS, Los Alamos Scientific Laboratory.
  
      Examples
      --------
      >>> x = [[1,2,3,5,1], [12,31,54, np.nan], [10,12,6,74,11]]
      >>> sp.posthoc_conover(x, p_adjust = 'holm')
      """
  
      def compare_conover(i, j):
          diff = np.abs(x_ranks_avg.loc[i] - x_ranks_avg.loc[j])
          B = 1.0 / x_lens.loc[i] + 1.0 / x_lens.loc[j]
          D = (n - 1.0 - h_cor) / (n - x_len)
          t_value = diff / np.sqrt(S2 * B * D)
          p_value = 2.0 * ss.t.sf(np.abs(t_value), df=n - x_len)
          return p_value
  
      x, _val_col, _group_col = __convert_to_df(a, val_col, group_col)
      x = (
          x.sort_values(by=[_group_col, _val_col], ascending=True)
          if sort
          else x
      )
  
      n = len(x.index)
      x_groups_unique = x[_group_col].unique()
      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()
      x_ranks_sum = x.groupby(_group_col)["ranks"].sum()
  
      # 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.0, 1.0 - tie_sum / (n**3.0 - n)])
  
      h = (12.0 / (n * (n + 1.0))) * np.sum(
          x_ranks_sum**2 / x_lens
      ) - 3.0 * (n + 1.0)
      h_cor = h / x_ties
  
      if x_ties == 1:
          S2 = n * (n + 1.0) / 12.0
      else:
          S2 = (1.0 / (n - 1.0)) * (
              np.sum(x["ranks"] ** 2.0)
              - (n * (((n + 1.0) ** 2.0) / 4.0))
          )
  
      vs = np.zeros((x_len, x_len))
      tri_upper = np.triu_indices(vs.shape[0], 1)
      tri_lower = np.tril_indices(vs.shape[0], -1)
      vs[:, :] = 0
  
      combs = it.combinations(range(x_len), 2)
  
      for i, j in combs:
          vs[i, j] = compare_conover(
              x_groups_unique[i], x_groups_unique[j]
          )
  
      if p_adjust:
          vs[tri_upper] = multipletests(vs[tri_upper], method=p_adjust)[
              1
          ]
      vs[tri_lower] = np.transpose(vs)[tri_lower]
      np.fill_diagonal(vs, 1)
  
      return DataFrame(
          vs, index=x_groups_unique, columns=x_groups_unique
      )
  
imports: import itertools
  from typing import Tuple, Union
  import numpy
  import scipy.stats
  from statsmodels.sandbox.stats.multicomp import multipletests
  from statsmodels.stats.multicomp import pairwise_tukeyhsd
  from statsmodels.stats.libqsturng import psturng
  from pandas import DataFrame
label_desc: Use image node_id 3 for calling a global function with example usage: posthoc_conover(a, val_col, group_col, p_adjust, sort) and returns: DataFrame, p_value