#NEWLINE# def test_ordinal_association( self , row_scores = None , col_scores = None ) : #NEWLINE# #INDENT# "\n        Assess independence between two ordinal variables.\n\n        This is the 'linear by linear' association test, which uses\n        weights or scores to target the test to have more power\n        against ordered alternatives.\n\n        Parameters\n        ----------\n        row_scores : array-like\n            An array of numeric row scores\n        col_scores : array-like\n            An array of numeric column scores\n\n        Returns\n        -------\n        A bunch with the following attributes:\n\n        statistic : float\n            The test statistic.\n        null_mean : float\n            The expected value of the test statistic under the null\n            hypothesis.\n        null_sd : float\n            The standard deviation of the test statistic under the\n            null hypothesis.\n        zscore : float\n            The Z-score for the test statistic.\n        pvalue : float\n            The p-value for the test.\n\n        Notes\n        -----\n        The scores define the trend to which the test is most sensitive.\n\n        Using the default row and column scores gives the\n        Cochran-Armitage trend test.\n        " #NEWLINE# if ( row_scores is None ) : #NEWLINE# #INDENT# row_scores = np . arange ( self . table . shape [ 0 ] ) #NEWLINE# #UNINDENT# if ( col_scores is None ) : #NEWLINE# #INDENT# col_scores = np . arange ( self . table . shape [ 1 ] ) #NEWLINE# #UNINDENT# if ( len ( row_scores ) != self . table . shape [ 0 ] ) : #NEWLINE# #INDENT# raise ValueError ( 'The length of `row_scores` must match the first dimension of `table`.' ) #NEWLINE# #UNINDENT# if ( len ( col_scores ) != self . table . shape [ 1 ] ) : #NEWLINE# #INDENT# raise ValueError ( 'The length of `col_scores` must match the second dimension of `table`.' ) #NEWLINE# #UNINDENT# statistic = np . dot ( row_scores , np . dot ( self . table , col_scores ) ) #NEWLINE# n_obs = self . table . sum ( ) #NEWLINE# rtot = self . table . sum ( 1 ) #NEWLINE# um = np . dot ( row_scores , rtot ) #NEWLINE# u2m = np . dot ( ( row_scores ** 2 ) , rtot ) #NEWLINE# ctot = self . table . sum ( 0 ) #NEWLINE# vn = np . dot ( col_scores , ctot ) #NEWLINE# v2n = np . dot ( ( col_scores ** 2 ) , ctot ) #NEWLINE# e_stat = ( ( um * vn ) / n_obs ) #NEWLINE# v_stat = ( ( ( u2m - ( ( um ** 2 ) / n_obs ) ) * ( v2n - ( ( vn ** 2 ) / n_obs ) ) ) / ( n_obs - 1 ) ) #NEWLINE# sd_stat = np . sqrt ( v_stat ) #NEWLINE# zscore = ( ( statistic - e_stat ) / sd_stat ) #NEWLINE# pvalue = ( 2 * stats . norm . cdf ( ( - np . abs ( zscore ) ) ) ) #NEWLINE# b = _Bunch ( ) #NEWLINE# b . statistic = statistic #NEWLINE# b . null_mean = e_stat #NEWLINE# b . null_sd = sd_stat #NEWLINE# b . zscore = zscore #NEWLINE# b . pvalue = pvalue #NEWLINE# return b