class_docstr: Methods for analyzing a square contingency table.
  
  Parameters
  ----------
  table : array_like
      A square contingency table, or DataFrame that is converted
      to a square form.
  shift_zeros : bool
      If True and any cell count is zero, add 0.5 to all values
      in the table.
  
  Notes
  -----
  These methods should only be used when the rows and columns of the
  table have the same categories.  If `table` is provided as a
  Pandas DataFrame, the row and column indices will be extended to
  create a square table, inserting zeros where a row or column is
  missing.  Otherwise the table should be provided in a square form,
  with the (implicit) row and column categories appearing in the
  same order.
class_docstr_tok: ["Methods","for","analyzing","a","square","contingency","table",".","Parameters","--","--","--","--","--","table",":","array_like","A","square","contingency","table",",","or","DataFrame","that","is","converted","to","a","square","form",".","shift_zeros",":","bool","If","True","and","any","cell","count","is","zero",",","add","0.5","to","all","values","in","the","table",".","Notes","--","--","-","These","methods","should","only","be","used","when","the","rows","and","columns","of","the","table","have","the","same","categories",".","If","`","table","`","is","provided","as","a","Pandas","DataFrame",",","the","row","and","column","indices","will","be","extended","to","create","a","square","table",",","inserting","zeros","where","a","row","or","column","is","missing",".","Otherwise","the","table","should","be","provided","in","a","square","form",",","with","the","(","implicit",")","row","and","column","categories","appearing","in","the","same","order","."]
docstr: Compare row and column marginal distributions.
  
  Parameters
  ----------
  method : str
      Either 'stuart_maxwell' or 'bhapkar', leading to two different
      estimates of the covariance matrix for the estimated
      difference between the row margins and the column margins.
  
  Returns
  -------
  Bunch
      A bunch with attributes:
  
      * statistic : float
          The chi^2 test statistic
      * pvalue : float
          The p-value of the test statistic
      * df : int
          The degrees of freedom of the reference distribution
  
  Notes
  -----
  For a 2x2 table this is equivalent to McNemar's test.  More
  generally the procedure tests the null hypothesis that the
  marginal distribution of the row factor is equal to the
  marginal distribution of the column factor.  For this to be
  meaningful, the two factors must have the same sample space
  (i.e. the same categories).
docstr_tok: ["Compare","row","and","column","marginal","distributions",".","Parameters","--","--","--","--","--","method",":","str","Either","'stuart_maxwell","'","or","'bhapkar","'",",","leading","to","two","different","estimates","of","the","covariance","matrix","for","the","estimated","difference","between","the","row","margins","and","the","column","margins",".","Returns","--","--","--","-","Bunch","A","bunch","with","attributes",":","*","statistic",":","float","The","chi^2","test","statistic","*","pvalue",":","float","The","p-value","of","the","test","statistic","*","df",":","int","The","degrees","of","freedom","of","the","reference","distribution","Notes","--","--","-","For","a","2x2","table","this","is","equivalent","to","McNemar","'s","test",".","More","generally","the","procedure","tests","the","null","hypothesis","that","the","marginal","distribution","of","the","row","factor","is","equal","to","the","marginal","distribution","of","the","column","factor",".","For","this","to","be","meaningful",",","the","two","factors","must","have","the","same","sample","space","(","i.e",".","the","same","categories",")","."]
code: def homogeneity(self, method="stuart_maxwell"):
      """
      Compare row and column marginal distributions.
  
      Parameters
      ----------
      method : str
          Either 'stuart_maxwell' or 'bhapkar', leading to two different
          estimates of the covariance matrix for the estimated
          difference between the row margins and the column margins.
  
      Returns
      -------
      Bunch
          A bunch with attributes:
  
          * statistic : float
              The chi^2 test statistic
          * pvalue : float
              The p-value of the test statistic
          * df : int
              The degrees of freedom of the reference distribution
  
      Notes
      -----
      For a 2x2 table this is equivalent to McNemar's test.  More
      generally the procedure tests the null hypothesis that the
      marginal distribution of the row factor is equal to the
      marginal distribution of the column factor.  For this to be
      meaningful, the two factors must have the same sample space
      (i.e. the same categories).
      """
  
      if self.table.shape[0] < 1:
          raise ValueError("table is empty")
      elif self.table.shape[0] == 1:
          b = _Bunch()
          b.statistic = 0
          b.pvalue = 1
          b.df = 0
          return b
  
      method = method.lower()
      if method not in ["bhapkar", "stuart_maxwell"]:
          raise ValueError(
              "method '%s' for homogeneity not known" % method
          )
  
      n_obs = self.table.sum()
      pr = self.table.astype(np.float64) / n_obs
  
      # Compute margins, eliminate last row/column so there is no
      # degeneracy
      row = pr.sum(1)[0:-1]
      col = pr.sum(0)[0:-1]
      pr = pr[0:-1, 0:-1]
  
      # The estimated difference between row and column margins.
      d = col - row
  
      # The degrees of freedom of the chi^2 reference distribution.
      df = pr.shape[0]
  
      if method == "bhapkar":
          vmat = -(pr + pr.T) - np.outer(d, d)
          dv = col + row - 2 * np.diag(pr) - d**2
          np.fill_diagonal(vmat, dv)
      elif method == "stuart_maxwell":
          vmat = -(pr + pr.T)
          dv = row + col - 2 * np.diag(pr)
          np.fill_diagonal(vmat, dv)
  
      try:
          statistic = n_obs * np.dot(d, np.linalg.solve(vmat, d))
      except np.linalg.LinAlgError:
          warnings.warn(
              "Unable to invert covariance matrix",
              sm_exceptions.SingularMatrixWarning,
          )
          b = _Bunch()
          b.statistic = np.nan
          b.pvalue = np.nan
          b.df = df
          return b
  
      pvalue = 1 - stats.chi2.cdf(statistic, df)
  
      b = _Bunch()
      b.statistic = statistic
      b.pvalue = pvalue
      b.df = df
  
      return b
  
imports: import warnings
  import numpy
  import pandas
  from scipy import stats
  from statsmodels import iolib
  from statsmodels.tools import sm_exceptions
  from statsmodels.tools.decorators import cache_readonly
label_desc: Use image node_id 3 for calling the SquareTable obj's underlying member method code with example usage: obj.homogeneity(method) and returns: b, b, b