code: def test_durbin(
      data: Union[List, np.ndarray, DataFrame],
      y_col: Union[str, int] = None,
      block_col: Union[str, int] = None,
      group_col: Union[str, int] = None,
      melted: bool = False,
      sort: bool = True,
  ) -> Tuple[float, float, int]:
      """Durbin's test whether k groups (or treatments) in a two-way
      balanced incomplete block design (BIBD) have identical effects. See
      references for additional information [1]_, [2]_.
  
      Parameters
      ----------
      data : Union[List, np.ndarray, DataFrame]
          An array, any object exposing the array interface or a pandas
          DataFrame with data values.
  
          If ``melted`` argument is set to False (default), ``a`` is a typical
          matrix of block design, i.e. rows are blocks, and columns are groups.
          In this case you do not need to specify col arguments.
  
          If ``a`` is an array and ``melted`` is set to True,
          y_col, block_col and group_col must specify the indices of columns
          containing elements of correspondary type.
  
          If ``a`` is a Pandas DataFrame and ``melted`` is set to True,
          y_col, block_col and group_col must specify columns names (string).
  
      y_col : Union[str, int] = None
          Must be specified if ``a`` is a pandas DataFrame object.
          Name of the column that contains y data.
  
      block_col : Union[str, int] = None
          Must be specified if ``a`` is a pandas DataFrame object.
          Name of the column that contains block names.
  
      group_col : Union[str, int] = None
          Must be specified if ``a`` is a pandas DataFrame object.
          Name of the column that contains group names.
  
      melted : bool = False
          Specifies if data are given as melted columns "y", "blocks", and
          "groups".
  
      sort : bool = False
          If True, sort data by block and group columns.
  
      Returns
      -------
      Tuple[float, float, int]
          P value, statistic, and number of degrees of freedom.
  
      References
      ----------
      .. [1] N. A. Heckert, J. J. Filliben. (2003) NIST Handbook 148: Dataplot Reference
          Manual, Volume 2: Let Subcommands and Library Functions. National Institute of
          Standards and Technology Handbook Series, June 2003.
      .. [2] W. J. Conover (1999), Practical nonparametric Statistics,
          3rd. edition, Wiley.
  
      Examples
      --------
      >>> x = np.array([[31,27,24],[31,28,31],[45,29,46],[21,18,48],[42,36,46],[32,17,40]])
      >>> sp.test_durbin(x)
      """
      if melted and not all([block_col, group_col, y_col]):
          raise ValueError(
              "block_col, group_col, y_col should be explicitly specified if using melted data"
          )
  
      x, _y_col, _group_col, _block_col = __convert_to_block_df(
          data, y_col, group_col, block_col, melted
      )
  
      groups = x[_group_col].unique()
      blocks = x[_block_col].unique()
      if not sort:
          x[_group_col] = Categorical(
              x[_group_col], categories=groups, ordered=True
          )
          x[_block_col] = Categorical(
              x[_block_col], categories=blocks, ordered=True
          )
      x.sort_values(
          by=[_block_col, _group_col], ascending=True, inplace=True
      )
      x.dropna(inplace=True)
  
      t = len(groups)
      b = len(blocks)
      r = np.unique(x.groupby(_group_col).count())
      k = np.unique(x.groupby(_block_col).count())
      if r.size > 1 and k.size > 1:
          raise ValueError(
              "Data appear to be unbalanced. Please correct your input data"
          )
      else:
          r = r.item()
          k = k.item()
      x["y_ranks"] = x.groupby(_block_col)[_y_col].rank()
      x["y_ranks_sum"] = x.groupby(_group_col)["y_ranks"].sum()
  
      A = np.sum(x["y_ranks"] ** 2.0)
      C = (b * k * (k + 1) ** 2.0) / 4.0
      D = np.sum(x["y_ranks_sum"] ** 2.0) - r * C
      T1 = (t - 1.0) / (A - C) * D
  
      stat = T1
      df = t - 1
      pval = ss.chi2.sf(stat, df)
  
      return pval, stat, df
  
file_path: scikit-posthocs/scikit_posthocs/_omnibus.py
imports: from typing import Union, List, Tuple
  import itertools
  import numpy
  import scipy.stats
  from statsmodels.stats.libqsturng import psturng
  from pandas import DataFrame, Categorical, Series
  from scikit_posthocs._posthocs import __convert_to_df, __convert_to_block_df
label_desc: Use image node_id 3 for calling a global function with example usage: test_durbin(data, y_col, block_col, group_col, melted, sort) and returns: pval,  stat,  df