'Assess independence between two ordinal variables.
This is the \'linear by linear\' association test, which uses
weights or scores to target the test to have more power
against ordered alternatives.
Parameters
row_scores : array-like
An array of numeric row scores
col_scores : array-like
An array of numeric column scores
Returns
A bunch with the following attributes:
statistic : float
The test statistic.
null_mean : float
The expected value of the test statistic under the null
hypothesis.
null_sd : float
The standard deviation of the test statistic under the
null hypothesis.
zscore : float
The Z-score for the test statistic.
pvalue : float
The p-value for the test.
Notes
The scores define the trend to which the test is most sensitive.
Using the default row and column scores gives the
Cochran-Armitage trend test.'

def test_ordinal_association(self, row_scores=None, col_scores=None):

    if (row_scores is None):
        row_scores = np.arange(self.table.shape[0])
    if (col_scores is None):
        col_scores = np.arange(self.table.shape[1])
    if (len(row_scores) != self.table.shape[0]):
        msg = ('The    length    of    `row_scores`    must    match    the    first    ' + 'dimension    of    `table`.')
        raise ValueError(msg)
    if (len(col_scores) != self.table.shape[1]):
        msg = ('The    length    of    `col_scores`    must    match    the    second    ' + 'dimension    of    `table`.')
        raise ValueError(msg)
    statistic = np.dot(row_scores, np.dot(self.table, col_scores))
    n_obs = self.table.sum()
    rtot = self.table.sum(1)
    um = np.dot(row_scores, rtot)
    u2m = np.dot((row_scores ** 2), rtot)
    ctot = self.table.sum(0)
    vn = np.dot(col_scores, ctot)
    v2n = np.dot((col_scores ** 2), ctot)
    e_stat = ((um * vn) / n_obs)
    v_stat = (((u2m - ((um ** 2) / n_obs)) * (v2n - ((vn ** 2) / n_obs))) / (n_obs - 1))
    sd_stat = np.sqrt(v_stat)
    zscore = ((statistic - e_stat) / sd_stat)
    pvalue = (2 * stats.norm.cdf((- np.abs(zscore))))
    b = _Bunch()
    b.statistic = statistic
    b.null_mean = e_stat
    b.null_sd = sd_stat
    b.zscore = zscore
    b.pvalue = pvalue
    return b
