'Test for symmetry of a joint distribution.
This procedure tests the null hypothesis that the joint
distribution is symmetric around the main diagonal, that is
.. math::
p_{i, j} = p_{j, i}  for all i, j
Returns
A bunch with attributes:
statistic : float
chisquare test statistic
p-value : float
p-value of the test statistic based on chisquare distribution
df : int
degrees of freedom of the chisquare distribution
Notes
The implementation is based on the SAS documentation. R includes
it in `mcnemar.test` if the table is not 2 by 2.  However a more
direct generalization of the McNemar test to larger tables is
provided by the homogeneity test (TableSymmetry.homogeneity).
The p-value is based on the chi-square distribution which requires
that the sample size is not very small to be a good approximation
of the true distribution. For 2x2 contingency tables the exact
distribution can be obtained with `mcnemar`
See Also
mcnemar
homogeneity'

def symmetry(self, method='bowker'):

    if (method.lower() != 'bowker'):
        raise ValueError("method    for    symmetry    testing    must    be    'bowker'")
    k = self.table.shape[0]
    upp_idx = np.triu_indices(k, 1)
    tril = self.table.T[upp_idx]
    triu = self.table[upp_idx]
    statistic = (((tril - triu) ** 2) / ((tril + triu) + 1e-20)).sum()
    df = ((k * (k - 1)) / 2.0)
    pvalue = stats.chi2.sf(statistic, df)
    b = _Bunch()
    b.statistic = statistic
    b.pvalue = pvalue
    b.df = df
    return b
