""" Test functions for stats module WRITTEN BY LOUIS LUANGKESORN FOR THE STATS MODULE BASED ON WILKINSON'S STATISTICS QUIZ http://www.stanford.edu/~clint/bench/wilk.txt Additional tests by a host of SciPy developers. """ from __future__ import division, print_function, absolute_import import sys import warnings from collections import namedtuple from numpy.testing import (TestCase, assert_, assert_equal, assert_almost_equal, assert_array_almost_equal, assert_array_equal, assert_approx_equal, assert_raises, run_module_suite, assert_allclose, dec) import numpy.ma.testutils as mat from numpy import array, arange, float32, float64, power import numpy as np import wafo.stats as stats """ Numbers in docstrings beginning with 'W' refer to the section numbers and headings found in the STATISTICS QUIZ of Leland Wilkinson. These are considered to be essential functionality. True testing and evaluation of a statistics package requires use of the NIST Statistical test data. See McCoullough(1999) Assessing The Reliability of Statistical Software for a test methodology and its implementation in testing SAS, SPSS, and S-Plus """ # Datasets # These data sets are from the nasty.dat sets used by Wilkinson # For completeness, I should write the relevant tests and count them as failures # Somewhat acceptable, since this is still beta software. It would count as a # good target for 1.0 status X = array([1,2,3,4,5,6,7,8,9], float) ZERO = array([0,0,0,0,0,0,0,0,0], float) BIG = array([99999991,99999992,99999993,99999994,99999995,99999996,99999997, 99999998,99999999], float) LITTLE = array([0.99999991,0.99999992,0.99999993,0.99999994,0.99999995,0.99999996, 0.99999997,0.99999998,0.99999999], float) HUGE = array([1e+12,2e+12,3e+12,4e+12,5e+12,6e+12,7e+12,8e+12,9e+12], float) TINY = array([1e-12,2e-12,3e-12,4e-12,5e-12,6e-12,7e-12,8e-12,9e-12], float) ROUND = array([0.5,1.5,2.5,3.5,4.5,5.5,6.5,7.5,8.5], float) class TestTrimmedStats(TestCase): # TODO: write these tests to handle missing values properly dprec = np.finfo(np.float64).precision def test_tmean(self): y = stats.tmean(X, (2, 8), (True, True)) assert_approx_equal(y, 5.0, significant=self.dprec) y1 = stats.tmean(X, limits=(2, 8), inclusive=(False, False)) y2 = stats.tmean(X, limits=None) assert_approx_equal(y1, y2, significant=self.dprec) def test_tvar(self): y = stats.tvar(X, limits=(2, 8), inclusive=(True, True)) assert_approx_equal(y, 4.6666666666666661, significant=self.dprec) y = stats.tvar(X, limits=None) assert_approx_equal(y, X.var(ddof=1), significant=self.dprec) def test_tstd(self): y = stats.tstd(X, (2, 8), (True, True)) assert_approx_equal(y, 2.1602468994692865, significant=self.dprec) y = stats.tstd(X, limits=None) assert_approx_equal(y, X.std(ddof=1), significant=self.dprec) def test_tmin(self): x = np.arange(10) assert_equal(stats.tmin(x), 0) assert_equal(stats.tmin(x, lowerlimit=0), 0) assert_equal(stats.tmin(x, lowerlimit=0, inclusive=False), 1) x = x.reshape((5, 2)) assert_equal(stats.tmin(x, lowerlimit=0, inclusive=False), [2, 1]) assert_equal(stats.tmin(x, axis=1), [0, 2, 4, 6, 8]) assert_equal(stats.tmin(x, axis=None), 0) def test_tmax(self): x = np.arange(10) assert_equal(stats.tmax(x), 9) assert_equal(stats.tmax(x, upperlimit=9),9) assert_equal(stats.tmax(x, upperlimit=9, inclusive=False), 8) x = x.reshape((5, 2)) assert_equal(stats.tmax(x, upperlimit=9, inclusive=False), [8, 7]) assert_equal(stats.tmax(x, axis=1), [1, 3, 5, 7, 9]) assert_equal(stats.tmax(x, axis=None), 9) def test_tsem(self): y = stats.tsem(X, limits=(3, 8), inclusive=(False, True)) y_ref = np.array([4, 5, 6, 7, 8]) assert_approx_equal(y, y_ref.std(ddof=1) / np.sqrt(y_ref.size), significant=self.dprec) assert_approx_equal(stats.tsem(X, limits=[-1, 10]), stats.tsem(X, limits=None), significant=self.dprec) class TestNanFunc(TestCase): def __init__(self, *args, **kw): TestCase.__init__(self, *args, **kw) self.X = X.copy() self.Xall = X.copy() self.Xall[:] = np.nan self.Xsome = X.copy() self.Xsomet = X.copy() self.Xsome[0] = np.nan self.Xsomet = self.Xsomet[1:] def test_nanmean_none(self): # Check nanmean when no values are nan. m = stats.nanmean(X) assert_approx_equal(m, X[4]) def test_nanmean_some(self): # Check nanmean when some values only are nan. m = stats.nanmean(self.Xsome) assert_approx_equal(m, 5.5) def test_nanmean_all(self): # Check nanmean when all values are nan. olderr = np.seterr(all='ignore') try: m = stats.nanmean(self.Xall) finally: np.seterr(**olderr) assert_(np.isnan(m)) def test_nanstd_none(self): # Check nanstd when no values are nan. s = stats.nanstd(self.X) assert_approx_equal(s, np.std(self.X, ddof=1)) def test_nanstd_some(self): # Check nanstd when some values only are nan. s = stats.nanstd(self.Xsome) assert_approx_equal(s, np.std(self.Xsomet, ddof=1)) def test_nanstd_all(self): # Check nanstd when all values are nan. olderr = np.seterr(all='ignore') try: s = stats.nanstd(self.Xall) finally: np.seterr(**olderr) assert_(np.isnan(s)) def test_nanstd_bias_kw(self): s = stats.nanstd(self.X, bias=True) assert_approx_equal(s, np.std(self.X, ddof=0)) def test_nanstd_negative_axis(self): x = np.array([1, 2, 3]) assert_equal(stats.nanstd(x, -1), 1) def test_nanmedian_none(self): # Check nanmedian when no values are nan. m = stats.nanmedian(self.X) assert_approx_equal(m, np.median(self.X)) def test_nanmedian_axis(self): # Check nanmedian with axis X = self.X.reshape(3,3) m = stats.nanmedian(X, axis=0) assert_equal(m, np.median(X, axis=0)) m = stats.nanmedian(X, axis=1) assert_equal(m, np.median(X, axis=1)) def test_nanmedian_some(self): # Check nanmedian when some values only are nan. m = stats.nanmedian(self.Xsome) assert_approx_equal(m, np.median(self.Xsomet)) def test_nanmedian_all(self): # Check nanmedian when all values are nan. with warnings.catch_warnings(record=True) as w: warnings.simplefilter('always') m = stats.nanmedian(self.Xall) assert_(np.isnan(m)) assert_equal(len(w), 1) assert_(issubclass(w[0].category, RuntimeWarning)) def test_nanmedian_all_axis(self): # Check nanmedian when all values are nan. with warnings.catch_warnings(record=True) as w: warnings.simplefilter('always') m = stats.nanmedian(self.Xall.reshape(3,3), axis=1) assert_(np.isnan(m).all()) assert_equal(len(w), 3) assert_(issubclass(w[0].category, RuntimeWarning)) def test_nanmedian_scalars(self): # Check nanmedian for scalar inputs. See ticket #1098. assert_equal(stats.nanmedian(1), np.median(1)) assert_equal(stats.nanmedian(True), np.median(True)) assert_equal(stats.nanmedian(np.array(1)), np.median(np.array(1))) assert_equal(stats.nanmedian(np.nan), np.median(np.nan)) class TestCorrPearsonr(TestCase): """ W.II.D. Compute a correlation matrix on all the variables. All the correlations, except for ZERO and MISS, shoud be exactly 1. ZERO and MISS should have undefined or missing correlations with the other variables. The same should go for SPEARMAN corelations, if your program has them. """ def test_pXX(self): y = stats.pearsonr(X,X) r = y[0] assert_approx_equal(r,1.0) def test_pXBIG(self): y = stats.pearsonr(X,BIG) r = y[0] assert_approx_equal(r,1.0) def test_pXLITTLE(self): y = stats.pearsonr(X,LITTLE) r = y[0] assert_approx_equal(r,1.0) def test_pXHUGE(self): y = stats.pearsonr(X,HUGE) r = y[0] assert_approx_equal(r,1.0) def test_pXTINY(self): y = stats.pearsonr(X,TINY) r = y[0] assert_approx_equal(r,1.0) def test_pXROUND(self): y = stats.pearsonr(X,ROUND) r = y[0] assert_approx_equal(r,1.0) def test_pBIGBIG(self): y = stats.pearsonr(BIG,BIG) r = y[0] assert_approx_equal(r,1.0) def test_pBIGLITTLE(self): y = stats.pearsonr(BIG,LITTLE) r = y[0] assert_approx_equal(r,1.0) def test_pBIGHUGE(self): y = stats.pearsonr(BIG,HUGE) r = y[0] assert_approx_equal(r,1.0) def test_pBIGTINY(self): y = stats.pearsonr(BIG,TINY) r = y[0] assert_approx_equal(r,1.0) def test_pBIGROUND(self): y = stats.pearsonr(BIG,ROUND) r = y[0] assert_approx_equal(r,1.0) def test_pLITTLELITTLE(self): y = stats.pearsonr(LITTLE,LITTLE) r = y[0] assert_approx_equal(r,1.0) def test_pLITTLEHUGE(self): y = stats.pearsonr(LITTLE,HUGE) r = y[0] assert_approx_equal(r,1.0) def test_pLITTLETINY(self): y = stats.pearsonr(LITTLE,TINY) r = y[0] assert_approx_equal(r,1.0) def test_pLITTLEROUND(self): y = stats.pearsonr(LITTLE,ROUND) r = y[0] assert_approx_equal(r,1.0) def test_pHUGEHUGE(self): y = stats.pearsonr(HUGE,HUGE) r = y[0] assert_approx_equal(r,1.0) def test_pHUGETINY(self): y = stats.pearsonr(HUGE,TINY) r = y[0] assert_approx_equal(r,1.0) def test_pHUGEROUND(self): y = stats.pearsonr(HUGE,ROUND) r = y[0] assert_approx_equal(r,1.0) def test_pTINYTINY(self): y = stats.pearsonr(TINY,TINY) r = y[0] assert_approx_equal(r,1.0) def test_pTINYROUND(self): y = stats.pearsonr(TINY,ROUND) r = y[0] assert_approx_equal(r,1.0) def test_pROUNDROUND(self): y = stats.pearsonr(ROUND,ROUND) r = y[0] assert_approx_equal(r,1.0) def test_r_exactly_pos1(self): a = arange(3.0) b = a r, prob = stats.pearsonr(a,b) assert_equal(r, 1.0) assert_equal(prob, 0.0) def test_r_exactly_neg1(self): a = arange(3.0) b = -a r, prob = stats.pearsonr(a,b) assert_equal(r, -1.0) assert_equal(prob, 0.0) def test_basic(self): # A basic test, with a correlation coefficient # that is not 1 or -1. a = array([-1, 0, 1]) b = array([0, 0, 3]) r, prob = stats.pearsonr(a, b) assert_approx_equal(r, np.sqrt(3)/2) assert_approx_equal(prob, 1.0/3) class TestFisherExact(TestCase): """Some tests to show that fisher_exact() works correctly. Note that in SciPy 0.9.0 this was not working well for large numbers due to inaccuracy of the hypergeom distribution (see #1218). Fixed now. Also note that R and Scipy have different argument formats for their hypergeometric distribution functions. R: > phyper(18999, 99000, 110000, 39000, lower.tail = FALSE) [1] 1.701815e-09 """ def test_basic(self): fisher_exact = stats.fisher_exact res = fisher_exact([[14500, 20000], [30000, 40000]])[1] assert_approx_equal(res, 0.01106, significant=4) res = fisher_exact([[100, 2], [1000, 5]])[1] assert_approx_equal(res, 0.1301, significant=4) res = fisher_exact([[2, 7], [8, 2]])[1] assert_approx_equal(res, 0.0230141, significant=6) res = fisher_exact([[5, 1], [10, 10]])[1] assert_approx_equal(res, 0.1973244, significant=6) res = fisher_exact([[5, 15], [20, 20]])[1] assert_approx_equal(res, 0.0958044, significant=6) res = fisher_exact([[5, 16], [20, 25]])[1] assert_approx_equal(res, 0.1725862, significant=6) res = fisher_exact([[10, 5], [10, 1]])[1] assert_approx_equal(res, 0.1973244, significant=6) res = fisher_exact([[5, 0], [1, 4]])[1] assert_approx_equal(res, 0.04761904, significant=6) res = fisher_exact([[0, 1], [3, 2]])[1] assert_approx_equal(res, 1.0) res = fisher_exact([[0, 2], [6, 4]])[1] assert_approx_equal(res, 0.4545454545) res = fisher_exact([[2, 7], [8, 2]]) assert_approx_equal(res[1], 0.0230141, significant=6) assert_approx_equal(res[0], 4.0 / 56) def test_precise(self): # results from R # # R defines oddsratio differently (see Notes section of fisher_exact # docstring), so those will not match. We leave them in anyway, in # case they will be useful later on. We test only the p-value. tablist = [ ([[100, 2], [1000, 5]], (2.505583993422285e-001, 1.300759363430016e-001)), ([[2, 7], [8, 2]], (8.586235135736206e-002, 2.301413756522114e-002)), ([[5, 1], [10, 10]], (4.725646047336584e+000, 1.973244147157190e-001)), ([[5, 15], [20, 20]], (3.394396617440852e-001, 9.580440012477637e-002)), ([[5, 16], [20, 25]], (3.960558326183334e-001, 1.725864953812994e-001)), ([[10, 5], [10, 1]], (2.116112781158483e-001, 1.973244147157190e-001)), ([[10, 5], [10, 0]], (0.000000000000000e+000, 6.126482213438734e-002)), ([[5, 0], [1, 4]], (np.inf, 4.761904761904762e-002)), ([[0, 5], [1, 4]], (0.000000000000000e+000, 1.000000000000000e+000)), ([[5, 1], [0, 4]], (np.inf, 4.761904761904758e-002)), ([[0, 1], [3, 2]], (0.000000000000000e+000, 1.000000000000000e+000)) ] for table, res_r in tablist: res = stats.fisher_exact(np.asarray(table)) np.testing.assert_almost_equal(res[1], res_r[1], decimal=11, verbose=True) @dec.slow def test_large_numbers(self): # Test with some large numbers. Regression test for #1401 pvals = [5.56e-11, 2.666e-11, 1.363e-11] # from R for pval, num in zip(pvals, [75, 76, 77]): res = stats.fisher_exact([[17704, 496], [1065, num]])[1] assert_approx_equal(res, pval, significant=4) res = stats.fisher_exact([[18000, 80000], [20000, 90000]])[1] assert_approx_equal(res, 0.2751, significant=4) def test_raises(self): # test we raise an error for wrong shape of input. assert_raises(ValueError, stats.fisher_exact, np.arange(6).reshape(2, 3)) def test_row_or_col_zero(self): tables = ([[0, 0], [5, 10]], [[5, 10], [0, 0]], [[0, 5], [0, 10]], [[5, 0], [10, 0]]) for table in tables: oddsratio, pval = stats.fisher_exact(table) assert_equal(pval, 1.0) assert_equal(oddsratio, np.nan) def test_less_greater(self): tables = ( # Some tables to compare with R: [[2, 7], [8, 2]], [[200, 7], [8, 300]], [[28, 21], [6, 1957]], [[190, 800], [200, 900]], # Some tables with simple exact values # (includes regression test for ticket #1568): [[0, 2], [3, 0]], [[1, 1], [2, 1]], [[2, 0], [1, 2]], [[0, 1], [2, 3]], [[1, 0], [1, 4]], ) pvals = ( # from R: [0.018521725952066501, 0.9990149169715733], [1.0, 2.0056578803889148e-122], [1.0, 5.7284374608319831e-44], [0.7416227, 0.2959826], # Exact: [0.1, 1.0], [0.7, 0.9], [1.0, 0.3], [2./3, 1.0], [1.0, 1./3], ) for table, pval in zip(tables, pvals): res = [] res.append(stats.fisher_exact(table, alternative="less")[1]) res.append(stats.fisher_exact(table, alternative="greater")[1]) assert_allclose(res, pval, atol=0, rtol=1e-7) def test_gh3014(self): # check if issue #3014 has been fixed. # before, this would have risen a ValueError odds, pvalue = stats.fisher_exact([[1, 2], [9, 84419233]]) class TestCorrSpearmanr(TestCase): """ W.II.D. Compute a correlation matrix on all the variables. All the correlations, except for ZERO and MISS, shoud be exactly 1. ZERO and MISS should have undefined or missing correlations with the other variables. The same should go for SPEARMAN corelations, if your program has them. """ def test_sXX(self): y = stats.spearmanr(X,X) r = y[0] assert_approx_equal(r,1.0) def test_sXBIG(self): y = stats.spearmanr(X,BIG) r = y[0] assert_approx_equal(r,1.0) def test_sXLITTLE(self): y = stats.spearmanr(X,LITTLE) r = y[0] assert_approx_equal(r,1.0) def test_sXHUGE(self): y = stats.spearmanr(X,HUGE) r = y[0] assert_approx_equal(r,1.0) def test_sXTINY(self): y = stats.spearmanr(X,TINY) r = y[0] assert_approx_equal(r,1.0) def test_sXROUND(self): y = stats.spearmanr(X,ROUND) r = y[0] assert_approx_equal(r,1.0) def test_sBIGBIG(self): y = stats.spearmanr(BIG,BIG) r = y[0] assert_approx_equal(r,1.0) def test_sBIGLITTLE(self): y = stats.spearmanr(BIG,LITTLE) r = y[0] assert_approx_equal(r,1.0) def test_sBIGHUGE(self): y = stats.spearmanr(BIG,HUGE) r = y[0] assert_approx_equal(r,1.0) def test_sBIGTINY(self): y = stats.spearmanr(BIG,TINY) r = y[0] assert_approx_equal(r,1.0) def test_sBIGROUND(self): y = stats.spearmanr(BIG,ROUND) r = y[0] assert_approx_equal(r,1.0) def test_sLITTLELITTLE(self): y = stats.spearmanr(LITTLE,LITTLE) r = y[0] assert_approx_equal(r,1.0) def test_sLITTLEHUGE(self): y = stats.spearmanr(LITTLE,HUGE) r = y[0] assert_approx_equal(r,1.0) def test_sLITTLETINY(self): y = stats.spearmanr(LITTLE,TINY) r = y[0] assert_approx_equal(r,1.0) def test_sLITTLEROUND(self): y = stats.spearmanr(LITTLE,ROUND) r = y[0] assert_approx_equal(r,1.0) def test_sHUGEHUGE(self): y = stats.spearmanr(HUGE,HUGE) r = y[0] assert_approx_equal(r,1.0) def test_sHUGETINY(self): y = stats.spearmanr(HUGE,TINY) r = y[0] assert_approx_equal(r,1.0) def test_sHUGEROUND(self): y = stats.spearmanr(HUGE,ROUND) r = y[0] assert_approx_equal(r,1.0) def test_sTINYTINY(self): y = stats.spearmanr(TINY,TINY) r = y[0] assert_approx_equal(r,1.0) def test_sTINYROUND(self): y = stats.spearmanr(TINY,ROUND) r = y[0] assert_approx_equal(r,1.0) def test_sROUNDROUND(self): y = stats.spearmanr(ROUND,ROUND) r = y[0] assert_approx_equal(r,1.0) class TestCorrSpearmanrTies(TestCase): """Some tests of tie-handling by the spearmanr function.""" def test_tie1(self): # Data x = [1.0, 2.0, 3.0, 4.0] y = [1.0, 2.0, 2.0, 3.0] # Ranks of the data, with tie-handling. xr = [1.0, 2.0, 3.0, 4.0] yr = [1.0, 2.5, 2.5, 4.0] # Result of spearmanr should be the same as applying # pearsonr to the ranks. sr = stats.spearmanr(x, y) pr = stats.pearsonr(xr, yr) assert_almost_equal(sr, pr) ## W.II.E. Tabulate X against X, using BIG as a case weight. The values ## should appear on the diagonal and the total should be 899999955. ## If the table cannot hold these values, forget about working with ## census data. You can also tabulate HUGE against TINY. There is no ## reason a tabulation program should not be able to distinguish ## different values regardless of their magnitude. ### I need to figure out how to do this one. def test_kendalltau(): # with some ties x1 = [12, 2, 1, 12, 2] x2 = [1, 4, 7, 1, 0] expected = (-0.47140452079103173, 0.24821309157521476) res = stats.kendalltau(x1, x2) assert_approx_equal(res[0], expected[0]) assert_approx_equal(res[1], expected[1]) # with only ties in one or both inputs assert_equal(stats.kendalltau([2,2,2], [2,2,2]), (np.nan, np.nan)) assert_equal(stats.kendalltau([2,0,2], [2,2,2]), (np.nan, np.nan)) assert_equal(stats.kendalltau([2,2,2], [2,0,2]), (np.nan, np.nan)) # empty arrays provided as input assert_equal(stats.kendalltau([], []), (np.nan, np.nan)) # check two different sort methods assert_approx_equal(stats.kendalltau(x1, x2, initial_lexsort=False)[1], stats.kendalltau(x1, x2, initial_lexsort=True)[1]) # and with larger arrays np.random.seed(7546) x = np.array([np.random.normal(loc=1, scale=1, size=500), np.random.normal(loc=1, scale=1, size=500)]) corr = [[1.0, 0.3], [0.3, 1.0]] x = np.dot(np.linalg.cholesky(corr), x) expected = (0.19291382765531062, 1.1337108207276285e-10) res = stats.kendalltau(x[0], x[1]) assert_approx_equal(res[0], expected[0]) assert_approx_equal(res[1], expected[1]) # and do we get a tau of 1 for identical inputs? assert_approx_equal(stats.kendalltau([1,1,2], [1,1,2])[0], 1.0) class TestRegression(TestCase): def test_linregressBIGX(self): # W.II.F. Regress BIG on X. # The constant should be 99999990 and the regression coefficient should be 1. y = stats.linregress(X,BIG) intercept = y[1] r = y[2] assert_almost_equal(intercept,99999990) assert_almost_equal(r,1.0) def test_regressXX(self): # W.IV.B. Regress X on X. # The constant should be exactly 0 and the regression coefficient should be 1. # This is a perfectly valid regression. The program should not complain. y = stats.linregress(X,X) intercept = y[1] r = y[2] assert_almost_equal(intercept,0.0) assert_almost_equal(r,1.0) ## W.IV.C. Regress X on BIG and LITTLE (two predictors). The program ## should tell you that this model is "singular" because BIG and ## LITTLE are linear combinations of each other. Cryptic error ## messages are unacceptable here. Singularity is the most ## fundamental regression error. ### Need to figure out how to handle multiple linear regression. Not obvious def test_regressZEROX(self): # W.IV.D. Regress ZERO on X. # The program should inform you that ZERO has no variance or it should # go ahead and compute the regression and report a correlation and # total sum of squares of exactly 0. y = stats.linregress(X,ZERO) intercept = y[1] r = y[2] assert_almost_equal(intercept,0.0) assert_almost_equal(r,0.0) def test_regress_simple(self): # Regress a line with sinusoidal noise. x = np.linspace(0, 100, 100) y = 0.2 * np.linspace(0, 100, 100) + 10 y += np.sin(np.linspace(0, 20, 100)) res = stats.linregress(x, y) assert_almost_equal(res[4], 2.3957814497838803e-3) def test_regress_simple_onearg_rows(self): # Regress a line w sinusoidal noise, with a single input of shape (2, N). x = np.linspace(0, 100, 100) y = 0.2 * np.linspace(0, 100, 100) + 10 y += np.sin(np.linspace(0, 20, 100)) rows = np.vstack((x, y)) res = stats.linregress(rows) assert_almost_equal(res[4], 2.3957814497838803e-3) def test_regress_simple_onearg_cols(self): x = np.linspace(0, 100, 100) y = 0.2 * np.linspace(0, 100, 100) + 10 y += np.sin(np.linspace(0, 20, 100)) cols = np.hstack((np.expand_dims(x, 1), np.expand_dims(y, 1))) res = stats.linregress(cols) assert_almost_equal(res[4], 2.3957814497838803e-3) def test_regress_shape_error(self): # Check that a single input argument to linregress with wrong shape # results in a ValueError. assert_raises(ValueError, stats.linregress, np.ones((3, 3))) def test_linregress(self): # compared with multivariate ols with pinv x = np.arange(11) y = np.arange(5,16) y[[(1),(-2)]] -= 1 y[[(0),(-1)]] += 1 res = (1.0, 5.0, 0.98229948625750, 7.45259691e-008, 0.063564172616372733) assert_array_almost_equal(stats.linregress(x,y),res,decimal=14) def test_regress_simple_negative_cor(self): # If the slope of the regression is negative the factor R tend to -1 not 1. # Sometimes rounding errors makes it < -1 leading to stderr being NaN a, n = 1e-71, 100000 x = np.linspace(a, 2 * a, n) y = np.linspace(2 * a, a, n) stats.linregress(x, y) res = stats.linregress(x, y) assert_(res[2] >= -1) # propagated numerical errors were not corrected assert_almost_equal(res[2], -1) # perfect negative correlation case assert_(not np.isnan(res[4])) # stderr should stay finite def test_theilslopes(): # Basic slope test. slope, intercept, lower, upper = stats.theilslopes([0,1,1]) assert_almost_equal(slope, 0.5) assert_almost_equal(intercept, 0.5) # Test of confidence intervals. x = [1, 2, 3, 4, 10, 12, 18] y = [9, 15, 19, 20, 45, 55, 78] slope, intercept, lower, upper = stats.theilslopes(y, x, 0.07) assert_almost_equal(slope, 4) assert_almost_equal(upper, 4.38, decimal=2) assert_almost_equal(lower, 3.71, decimal=2) class TestHistogram(TestCase): # Tests that histogram works as it should, and keeps old behaviour # # what is untested: # - multidimensional arrays (since 'a' is ravel'd as the first line in the method) # - very large arrays # - Nans, Infs, empty and otherwise bad inputs # sample arrays to test the histogram with low_values = np.array([0.2, 0.3, 0.4, 0.5, 0.5, 0.6, 0.7, 0.8, 0.9, 1.1, 1.2], dtype=float) # 11 values high_range = np.array([2, 3, 4, 2, 21, 32, 78, 95, 65, 66, 66, 66, 66, 4], dtype=float) # 14 values low_range = np.array([2, 3, 3, 2, 3, 2.4, 2.1, 3.1, 2.9, 2.6, 2.7, 2.8, 2.2, 2.001], dtype=float) # 14 values few_values = np.array([2.0, 3.0, -1.0, 0.0], dtype=float) # 4 values def test_simple(self): # Tests that each of the tests works as expected with default params # # basic tests, with expected results (no weighting) # results taken from the previous (slower) version of histogram basic_tests = ((self.low_values, (np.array([1., 1., 1., 2., 2., 1., 1., 0., 1., 1.]), 0.14444444444444446, 0.11111111111111112, 0)), (self.high_range, (np.array([5., 0., 1., 1., 0., 0., 5., 1., 0., 1.]), -3.1666666666666661, 10.333333333333332, 0)), (self.low_range, (np.array([3., 1., 1., 1., 0., 1., 1., 2., 3., 1.]), 1.9388888888888889, 0.12222222222222223, 0)), (self.few_values, (np.array([1., 0., 1., 0., 0., 0., 0., 1., 0., 1.]), -1.2222222222222223, 0.44444444444444448, 0)), ) for inputs, expected_results in basic_tests: given_results = stats.histogram(inputs) assert_array_almost_equal(expected_results[0], given_results[0], decimal=2) for i in range(1, 4): assert_almost_equal(expected_results[i], given_results[i], decimal=2) def test_weighting(self): # Tests that weights give expected histograms # basic tests, with expected results, given a set of weights # weights used (first n are used for each test, where n is len of array) (14 values) weights = np.array([1., 3., 4.5, 0.1, -1.0, 0.0, 0.3, 7.0, 103.2, 2, 40, 0, 0, 1]) # results taken from the numpy version of histogram basic_tests = ((self.low_values, (np.array([4.0, 0.0, 4.5, -0.9, 0.0, 0.3,110.2, 0.0, 0.0, 42.0]), 0.2, 0.1, 0)), (self.high_range, (np.array([9.6, 0., -1., 0., 0., 0.,145.2, 0., 0.3, 7.]), 2.0, 9.3, 0)), (self.low_range, (np.array([2.4, 0., 0., 0., 0., 2., 40., 0., 103.2, 13.5]), 2.0, 0.11, 0)), (self.few_values, (np.array([4.5, 0., 0.1, 0., 0., 0., 0., 1., 0., 3.]), -1., 0.4, 0)), ) for inputs, expected_results in basic_tests: # use the first lot of weights for test # default limits given to reproduce output of numpy's test better given_results = stats.histogram(inputs, defaultlimits=(inputs.min(), inputs.max()), weights=weights[:len(inputs)]) assert_array_almost_equal(expected_results[0], given_results[0], decimal=2) for i in range(1, 4): assert_almost_equal(expected_results[i], given_results[i], decimal=2) def test_reduced_bins(self): # Tests that reducing the number of bins produces expected results # basic tests, with expected results (no weighting), # except number of bins is halved to 5 # results taken from the previous (slower) version of histogram basic_tests = ((self.low_values, (np.array([2., 3., 3., 1., 2.]), 0.075000000000000011, 0.25, 0)), (self.high_range, (np.array([5., 2., 0., 6., 1.]), -9.625, 23.25, 0)), (self.low_range, (np.array([4., 2., 1., 3., 4.]), 1.8625, 0.27500000000000002, 0)), (self.few_values, (np.array([1., 1., 0., 1., 1.]), -1.5, 1.0, 0)), ) for inputs, expected_results in basic_tests: given_results = stats.histogram(inputs, numbins=5) assert_array_almost_equal(expected_results[0], given_results[0], decimal=2) for i in range(1, 4): assert_almost_equal(expected_results[i], given_results[i], decimal=2) def test_increased_bins(self): # Tests that increasing the number of bins produces expected results # basic tests, with expected results (no weighting), # except number of bins is double to 20 # results taken from the previous (slower) version of histogram basic_tests = ((self.low_values, (np.array([1., 0., 1., 0., 1., 0., 2., 0., 1., 0., 1., 1., 0., 1., 0., 0., 0., 1., 0., 1.]), 0.1736842105263158, 0.052631578947368418, 0)), (self.high_range, (np.array([5., 0., 0., 0., 1., 0., 1., 0., 0., 0., 0., 0., 0., 5., 0., 0., 1., 0., 0., 1.]), -0.44736842105263142, 4.8947368421052628, 0)), (self.low_range, (np.array([3., 0., 1., 1., 0., 0., 0., 1., 0., 0., 1., 0., 1., 0., 1., 0., 1., 3., 0., 1.]), 1.9710526315789474, 0.057894736842105263, 0)), (self.few_values, (np.array([1., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 1.]), -1.1052631578947367, 0.21052631578947367, 0)), ) for inputs, expected_results in basic_tests: given_results = stats.histogram(inputs, numbins=20) assert_array_almost_equal(expected_results[0], given_results[0], decimal=2) for i in range(1, 4): assert_almost_equal(expected_results[i], given_results[i], decimal=2) def test_cumfreq(): x = [1, 4, 2, 1, 3, 1] cumfreqs, lowlim, binsize, extrapoints = stats.cumfreq(x, numbins=4) assert_array_almost_equal(cumfreqs, np.array([3., 4., 5., 6.])) cumfreqs, lowlim, binsize, extrapoints = stats.cumfreq(x, numbins=4, defaultreallimits=(1.5, 5)) assert_(extrapoints == 3) def test_relfreq(): a = np.array([1, 4, 2, 1, 3, 1]) relfreqs, lowlim, binsize, extrapoints = stats.relfreq(a, numbins=4) assert_array_almost_equal(relfreqs, array([0.5, 0.16666667, 0.16666667, 0.16666667])) # check array_like input is accepted relfreqs2, lowlim, binsize, extrapoints = stats.relfreq([1, 4, 2, 1, 3, 1], numbins=4) assert_array_almost_equal(relfreqs, relfreqs2) class TestGMean(TestCase): def test_1D_list(self): a = (1,2,3,4) actual = stats.gmean(a) desired = power(1*2*3*4,1./4.) assert_almost_equal(actual, desired,decimal=14) desired1 = stats.gmean(a,axis=-1) assert_almost_equal(actual, desired1, decimal=14) def test_1D_array(self): a = array((1,2,3,4), float32) actual = stats.gmean(a) desired = power(1*2*3*4,1./4.) assert_almost_equal(actual, desired, decimal=7) desired1 = stats.gmean(a,axis=-1) assert_almost_equal(actual, desired1, decimal=7) def test_2D_array_default(self): a = array(((1,2,3,4), (1,2,3,4), (1,2,3,4))) actual = stats.gmean(a) desired = array((1,2,3,4)) assert_array_almost_equal(actual, desired, decimal=14) desired1 = stats.gmean(a,axis=0) assert_array_almost_equal(actual, desired1, decimal=14) def test_2D_array_dim1(self): a = array(((1,2,3,4), (1,2,3,4), (1,2,3,4))) actual = stats.gmean(a, axis=1) v = power(1*2*3*4,1./4.) desired = array((v,v,v)) assert_array_almost_equal(actual, desired, decimal=14) def test_large_values(self): a = array([1e100, 1e200, 1e300]) actual = stats.gmean(a) assert_approx_equal(actual, 1e200, significant=14) class TestHMean(TestCase): def test_1D_list(self): a = (1,2,3,4) actual = stats.hmean(a) desired = 4. / (1./1 + 1./2 + 1./3 + 1./4) assert_almost_equal(actual, desired, decimal=14) desired1 = stats.hmean(array(a),axis=-1) assert_almost_equal(actual, desired1, decimal=14) def test_1D_array(self): a = array((1,2,3,4), float64) actual = stats.hmean(a) desired = 4. / (1./1 + 1./2 + 1./3 + 1./4) assert_almost_equal(actual, desired, decimal=14) desired1 = stats.hmean(a,axis=-1) assert_almost_equal(actual, desired1, decimal=14) def test_2D_array_default(self): a = array(((1,2,3,4), (1,2,3,4), (1,2,3,4))) actual = stats.hmean(a) desired = array((1.,2.,3.,4.)) assert_array_almost_equal(actual, desired, decimal=14) actual1 = stats.hmean(a,axis=0) assert_array_almost_equal(actual1, desired, decimal=14) def test_2D_array_dim1(self): a = array(((1,2,3,4), (1,2,3,4), (1,2,3,4))) v = 4. / (1./1 + 1./2 + 1./3 + 1./4) desired1 = array((v,v,v)) actual1 = stats.hmean(a, axis=1) assert_array_almost_equal(actual1, desired1, decimal=14) class TestScoreatpercentile(TestCase): def setUp(self): self.a1 = [3, 4, 5, 10, -3, -5, 6] self.a2 = [3, -6, -2, 8, 7, 4, 2, 1] self.a3 = [3., 4, 5, 10, -3, -5, -6, 7.0] def test_basic(self): x = arange(8) * 0.5 assert_equal(stats.scoreatpercentile(x, 0), 0.) assert_equal(stats.scoreatpercentile(x, 100), 3.5) assert_equal(stats.scoreatpercentile(x, 50), 1.75) def test_2D(self): x = array([[1, 1, 1], [1, 1, 1], [4, 4, 3], [1, 1, 1], [1, 1, 1]]) assert_array_equal(stats.scoreatpercentile(x, 50), [1, 1, 1]) def test_fraction(self): scoreatperc = stats.scoreatpercentile # Test defaults assert_equal(scoreatperc(list(range(10)), 50), 4.5) assert_equal(scoreatperc(list(range(10)), 50, (2,7)), 4.5) assert_equal(scoreatperc(list(range(100)), 50, limit=(1, 8)), 4.5) assert_equal(scoreatperc(np.array([1, 10,100]), 50, (10,100)), 55) assert_equal(scoreatperc(np.array([1, 10,100]), 50, (1,10)), 5.5) # explicitly specify interpolation_method 'fraction' (the default) assert_equal(scoreatperc(list(range(10)), 50, interpolation_method='fraction'), 4.5) assert_equal(scoreatperc(list(range(10)), 50, limit=(2, 7), interpolation_method='fraction'), 4.5) assert_equal(scoreatperc(list(range(100)), 50, limit=(1, 8), interpolation_method='fraction'), 4.5) assert_equal(scoreatperc(np.array([1, 10,100]), 50, (10, 100), interpolation_method='fraction'), 55) assert_equal(scoreatperc(np.array([1, 10,100]), 50, (1,10), interpolation_method='fraction'), 5.5) def test_lower_higher(self): scoreatperc = stats.scoreatpercentile # interpolation_method 'lower'/'higher' assert_equal(scoreatperc(list(range(10)), 50, interpolation_method='lower'), 4) assert_equal(scoreatperc(list(range(10)), 50, interpolation_method='higher'), 5) assert_equal(scoreatperc(list(range(10)), 50, (2,7), interpolation_method='lower'), 4) assert_equal(scoreatperc(list(range(10)), 50, limit=(2,7), interpolation_method='higher'), 5) assert_equal(scoreatperc(list(range(100)), 50, (1,8), interpolation_method='lower'), 4) assert_equal(scoreatperc(list(range(100)), 50, (1,8), interpolation_method='higher'), 5) assert_equal(scoreatperc(np.array([1, 10, 100]), 50, (10, 100), interpolation_method='lower'), 10) assert_equal(scoreatperc(np.array([1, 10, 100]), 50, limit=(10, 100), interpolation_method='higher'), 100) assert_equal(scoreatperc(np.array([1, 10, 100]), 50, (1, 10), interpolation_method='lower'), 1) assert_equal(scoreatperc(np.array([1, 10, 100]), 50, limit=(1, 10), interpolation_method='higher'), 10) def test_sequence_per(self): x = arange(8) * 0.5 expected = np.array([0, 3.5, 1.75]) res = stats.scoreatpercentile(x, [0, 100, 50]) assert_allclose(res, expected) assert_(isinstance(res, np.ndarray)) # Test with ndarray. Regression test for gh-2861 assert_allclose(stats.scoreatpercentile(x, np.array([0, 100, 50])), expected) # Also test combination of 2-D array, axis not None and array-like per res2 = stats.scoreatpercentile(np.arange(12).reshape((3,4)), np.array([0, 1, 100, 100]), axis=1) expected2 = array([[0, 4, 8], [0.03, 4.03, 8.03], [3, 7, 11], [3, 7, 11]]) assert_allclose(res2, expected2) def test_axis(self): scoreatperc = stats.scoreatpercentile x = arange(12).reshape(3, 4) assert_equal(scoreatperc(x, (25, 50, 100)), [2.75, 5.5, 11.0]) r0 = [[2, 3, 4, 5], [4, 5, 6, 7], [8, 9, 10, 11]] assert_equal(scoreatperc(x, (25, 50, 100), axis=0), r0) r1 = [[0.75, 4.75, 8.75], [1.5, 5.5, 9.5], [3, 7, 11]] assert_equal(scoreatperc(x, (25, 50, 100), axis=1), r1) def test_exception(self): assert_raises(ValueError, stats.scoreatpercentile, [1, 2], 56, interpolation_method='foobar') assert_raises(ValueError, stats.scoreatpercentile, [1], 101) assert_raises(ValueError, stats.scoreatpercentile, [1], -1) def test_empty(self): assert_equal(stats.scoreatpercentile([], 50), np.nan) assert_equal(stats.scoreatpercentile(np.array([[], []]), 50), np.nan) assert_equal(stats.scoreatpercentile([], [50, 99]), [np.nan, np.nan]) class TestItemfreq(object): a = [5, 7, 1, 2, 1, 5, 7] * 10 b = [1, 2, 5, 7] def test_numeric_types(self): # Check itemfreq works for all dtypes (adapted from np.unique tests) def _check_itemfreq(dt): a = np.array(self.a, dt) v = stats.itemfreq(a) assert_array_equal(v[:, 0], [1, 2, 5, 7]) assert_array_equal(v[:, 1], np.array([20, 10, 20, 20], dtype=dt)) dtypes = [np.int32, np.int64, np.float32, np.float64, np.complex64, np.complex128] for dt in dtypes: yield _check_itemfreq, dt def test_object_arrays(self): a, b = self.a, self.b dt = 'O' aa = np.empty(len(a), dt) aa[:] = a bb = np.empty(len(b), dt) bb[:] = b v = stats.itemfreq(aa) assert_array_equal(v[:, 0], bb) def test_structured_arrays(self): a, b = self.a, self.b dt = [('', 'i'), ('', 'i')] aa = np.array(list(zip(a, a)), dt) bb = np.array(list(zip(b, b)), dt) v = stats.itemfreq(aa) # Arrays don't compare equal because v[:,0] is object array assert_equal(tuple(v[2, 0]), tuple(bb[2])) class TestMode(TestCase): def test_basic(self): data1 = [3,5,1,10,23,3,2,6,8,6,10,6] vals = stats.mode(data1) assert_almost_equal(vals[0][0],6) assert_almost_equal(vals[1][0],3) def test_axes(self): data1 = [10,10,30,40] data2 = [10,10,10,10] data3 = [20,10,20,20] data4 = [30,30,30,30] data5 = [40,30,30,30] arr = np.array([data1, data2, data3, data4, data5]) vals = stats.mode(arr, axis=None) assert_almost_equal(vals[0],np.array([30])) assert_almost_equal(vals[1],np.array([8])) vals = stats.mode(arr, axis=0) assert_almost_equal(vals[0],np.array([[10,10,30,30]])) assert_almost_equal(vals[1],np.array([[2,3,3,2]])) vals = stats.mode(arr, axis=1) assert_almost_equal(vals[0],np.array([[10],[10],[20],[30],[30]])) assert_almost_equal(vals[1],np.array([[2],[4],[3],[4],[3]])) def test_strings(self): data1 = ['rain', 'showers', 'showers'] vals = stats.mode(data1) expected = ['showers'] assert_equal(vals[0][0], 'showers') assert_equal(vals[1][0], 2) @dec.knownfailureif(sys.version_info > (3,), 'numpy github issue 641') def test_mixed_objects(self): objects = [10, True, np.nan, 'hello', 10] arr = np.empty((5,), dtype=object) arr[:] = objects vals = stats.mode(arr) assert_equal(vals[0][0], 10) assert_equal(vals[1][0], 2) def test_objects(self): """Python objects must be sortable (le + eq) and have ne defined for np.unique to work. hash is for set. """ class Point(object): def __init__(self, x): self.x = x def __eq__(self, other): return self.x == other.x def __ne__(self, other): return self.x != other.x def __lt__(self, other): return self.x < other.x def __hash__(self): return hash(self.x) points = [Point(x) for x in [1,2,3,4,3,2,2,2]] arr = np.empty((8,), dtype=object) arr[:] = points assert len(set(points)) == 4 assert_equal(np.unique(arr).shape, (4,)) vals = stats.mode(arr) assert_equal(vals[0][0], Point(2)) assert_equal(vals[1][0], 4) class TestVariability(TestCase): testcase = [1,2,3,4] def test_signaltonoise(self): # This is not in R, so used: # mean(testcase, axis=0) / (sqrt(var(testcase) * 3/4)) # y = stats.signaltonoise(self.shoes[0]) # assert_approx_equal(y,4.5709967) y = stats.signaltonoise(self.testcase) assert_approx_equal(y,2.236067977) def test_sem(self): # This is not in R, so used: # sqrt(var(testcase)*3/4)/sqrt(3) # y = stats.sem(self.shoes[0]) # assert_approx_equal(y,0.775177399) y = stats.sem(self.testcase) assert_approx_equal(y, 0.6454972244) n = len(self.testcase) assert_allclose(stats.sem(self.testcase, ddof=0) * np.sqrt(n/(n-2)), stats.sem(self.testcase, ddof=2)) def test_zmap(self): # not in R, so tested by using: # (testcase[i] - mean(testcase, axis=0)) / sqrt(var(testcase) * 3/4) y = stats.zmap(self.testcase,self.testcase) desired = ([-1.3416407864999, -0.44721359549996, 0.44721359549996, 1.3416407864999]) assert_array_almost_equal(desired,y,decimal=12) def test_zmap_axis(self): # Test use of 'axis' keyword in zmap. x = np.array([[0.0, 0.0, 1.0, 1.0], [1.0, 1.0, 1.0, 2.0], [2.0, 0.0, 2.0, 0.0]]) t1 = 1.0/np.sqrt(2.0/3) t2 = np.sqrt(3.)/3 t3 = np.sqrt(2.) z0 = stats.zmap(x, x, axis=0) z1 = stats.zmap(x, x, axis=1) z0_expected = [[-t1, -t3/2, -t3/2, 0.0], [0.0, t3, -t3/2, t1], [t1, -t3/2, t3, -t1]] z1_expected = [[-1.0, -1.0, 1.0, 1.0], [-t2, -t2, -t2, np.sqrt(3.)], [1.0, -1.0, 1.0, -1.0]] assert_array_almost_equal(z0, z0_expected) assert_array_almost_equal(z1, z1_expected) def test_zmap_ddof(self): # Test use of 'ddof' keyword in zmap. x = np.array([[0.0, 0.0, 1.0, 1.0], [0.0, 1.0, 2.0, 3.0]]) z = stats.zmap(x, x, axis=1, ddof=1) z0_expected = np.array([-0.5, -0.5, 0.5, 0.5])/(1.0/np.sqrt(3)) z1_expected = np.array([-1.5, -0.5, 0.5, 1.5])/(np.sqrt(5./3)) assert_array_almost_equal(z[0], z0_expected) assert_array_almost_equal(z[1], z1_expected) def test_zscore(self): # not in R, so tested by using: # (testcase[i] - mean(testcase, axis=0)) / sqrt(var(testcase) * 3/4) y = stats.zscore(self.testcase) desired = ([-1.3416407864999, -0.44721359549996, 0.44721359549996, 1.3416407864999]) assert_array_almost_equal(desired,y,decimal=12) def test_zscore_axis(self): # Test use of 'axis' keyword in zscore. x = np.array([[0.0, 0.0, 1.0, 1.0], [1.0, 1.0, 1.0, 2.0], [2.0, 0.0, 2.0, 0.0]]) t1 = 1.0/np.sqrt(2.0/3) t2 = np.sqrt(3.)/3 t3 = np.sqrt(2.) z0 = stats.zscore(x, axis=0) z1 = stats.zscore(x, axis=1) z0_expected = [[-t1, -t3/2, -t3/2, 0.0], [0.0, t3, -t3/2, t1], [t1, -t3/2, t3, -t1]] z1_expected = [[-1.0, -1.0, 1.0, 1.0], [-t2, -t2, -t2, np.sqrt(3.)], [1.0, -1.0, 1.0, -1.0]] assert_array_almost_equal(z0, z0_expected) assert_array_almost_equal(z1, z1_expected) def test_zscore_ddof(self): # Test use of 'ddof' keyword in zscore. x = np.array([[0.0, 0.0, 1.0, 1.0], [0.0, 1.0, 2.0, 3.0]]) z = stats.zscore(x, axis=1, ddof=1) z0_expected = np.array([-0.5, -0.5, 0.5, 0.5])/(1.0/np.sqrt(3)) z1_expected = np.array([-1.5, -0.5, 0.5, 1.5])/(np.sqrt(5./3)) assert_array_almost_equal(z[0], z0_expected) assert_array_almost_equal(z[1], z1_expected) class TestMoments(TestCase): """ Comparison numbers are found using R v.1.5.1 note that length(testcase) = 4 testmathworks comes from documentation for the Statistics Toolbox for Matlab and can be found at both http://www.mathworks.com/access/helpdesk/help/toolbox/stats/kurtosis.shtml http://www.mathworks.com/access/helpdesk/help/toolbox/stats/skewness.shtml Note that both test cases came from here. """ testcase = [1,2,3,4] testmathworks = [1.165, 0.6268, 0.0751, 0.3516, -0.6965] def test_moment(self): # mean((testcase-mean(testcase))**power,axis=0),axis=0))**power)) y = stats.moment(self.testcase,1) assert_approx_equal(y,0.0,10) y = stats.moment(self.testcase,2) assert_approx_equal(y,1.25) y = stats.moment(self.testcase,3) assert_approx_equal(y,0.0) y = stats.moment(self.testcase,4) assert_approx_equal(y,2.5625) def test_variation(self): # variation = samplestd / mean y = stats.variation(self.testcase) assert_approx_equal(y,0.44721359549996, 10) def test_skewness(self): # sum((testmathworks-mean(testmathworks,axis=0))**3,axis=0) / # ((sqrt(var(testmathworks)*4/5))**3)/5 y = stats.skew(self.testmathworks) assert_approx_equal(y,-0.29322304336607,10) y = stats.skew(self.testmathworks,bias=0) assert_approx_equal(y,-0.437111105023940,10) y = stats.skew(self.testcase) assert_approx_equal(y,0.0,10) def test_skewness_scalar(self): # `skew` must return a scalar for 1-dim input assert_equal(stats.skew(arange(10)), 0.0) def test_kurtosis(self): # sum((testcase-mean(testcase,axis=0))**4,axis=0)/((sqrt(var(testcase)*3/4))**4)/4 # sum((test2-mean(testmathworks,axis=0))**4,axis=0)/((sqrt(var(testmathworks)*4/5))**4)/5 # Set flags for axis = 0 and # fisher=0 (Pearson's defn of kurtosis for compatiability with Matlab) y = stats.kurtosis(self.testmathworks,0,fisher=0,bias=1) assert_approx_equal(y, 2.1658856802973,10) # Note that MATLAB has confusing docs for the following case # kurtosis(x,0) gives an unbiased estimate of Pearson's skewness # kurtosis(x) gives a biased estimate of Fisher's skewness (Pearson-3) # The MATLAB docs imply that both should give Fisher's y = stats.kurtosis(self.testmathworks,fisher=0,bias=0) assert_approx_equal(y, 3.663542721189047,10) y = stats.kurtosis(self.testcase,0,0) assert_approx_equal(y,1.64) def test_kurtosis_array_scalar(self): assert_equal(type(stats.kurtosis([1,2,3])), float) class TestThreshold(TestCase): def test_basic(self): a = [-1,2,3,4,5,-1,-2] assert_array_equal(stats.threshold(a),a) assert_array_equal(stats.threshold(a,3,None,0), [0,0,3,4,5,0,0]) assert_array_equal(stats.threshold(a,None,3,0), [-1,2,3,0,0,-1,-2]) assert_array_equal(stats.threshold(a,2,4,0), [0,2,3,4,0,0,0]) class TestStudentTest(TestCase): X1 = np.array([-1, 0, 1]) X2 = np.array([0, 1, 2]) T1_0 = 0 P1_0 = 1 T1_1 = -1.732051 P1_1 = 0.2254033 T1_2 = -3.464102 P1_2 = 0.0741799 T2_0 = 1.732051 P2_0 = 0.2254033 def test_onesample(self): t, p = stats.ttest_1samp(self.X1, 0) assert_array_almost_equal(t, self.T1_0) assert_array_almost_equal(p, self.P1_0) t, p = stats.ttest_1samp(self.X2, 0) assert_array_almost_equal(t, self.T2_0) assert_array_almost_equal(p, self.P2_0) t, p = stats.ttest_1samp(self.X1, 1) assert_array_almost_equal(t, self.T1_1) assert_array_almost_equal(p, self.P1_1) t, p = stats.ttest_1samp(self.X1, 2) assert_array_almost_equal(t, self.T1_2) assert_array_almost_equal(p, self.P1_2) def test_percentileofscore(): pcos = stats.percentileofscore assert_equal(pcos([1,2,3,4,5,6,7,8,9,10],4), 40.0) for (kind, result) in [('mean', 35.0), ('strict', 30.0), ('weak', 40.0)]: yield assert_equal, pcos(np.arange(10) + 1, 4, kind=kind), \ result # multiple - 2 for (kind, result) in [('rank', 45.0), ('strict', 30.0), ('weak', 50.0), ('mean', 40.0)]: yield assert_equal, pcos([1,2,3,4,4,5,6,7,8,9], 4, kind=kind), \ result # multiple - 3 assert_equal(pcos([1,2,3,4,4,4,5,6,7,8], 4), 50.0) for (kind, result) in [('rank', 50.0), ('mean', 45.0), ('strict', 30.0), ('weak', 60.0)]: yield assert_equal, pcos([1,2,3,4,4,4,5,6,7,8], 4, kind=kind), \ result # missing for kind in ('rank', 'mean', 'strict', 'weak'): yield assert_equal, pcos([1,2,3,5,6,7,8,9,10,11], 4, kind=kind), \ 30 # larger numbers for (kind, result) in [('mean', 35.0), ('strict', 30.0), ('weak', 40.0)]: yield assert_equal, \ pcos([10, 20, 30, 40, 50, 60, 70, 80, 90, 100], 40, kind=kind), result for (kind, result) in [('mean', 45.0), ('strict', 30.0), ('weak', 60.0)]: yield assert_equal, \ pcos([10, 20, 30, 40, 40, 40, 50, 60, 70, 80], 40, kind=kind), result for kind in ('rank', 'mean', 'strict', 'weak'): yield assert_equal, \ pcos([10, 20, 30, 50, 60, 70, 80, 90, 100, 110], 40, kind=kind), 30.0 # boundaries for (kind, result) in [('rank', 10.0), ('mean', 5.0), ('strict', 0.0), ('weak', 10.0)]: yield assert_equal, \ pcos([10, 20, 30, 50, 60, 70, 80, 90, 100, 110], 10, kind=kind), result for (kind, result) in [('rank', 100.0), ('mean', 95.0), ('strict', 90.0), ('weak', 100.0)]: yield assert_equal, \ pcos([10, 20, 30, 50, 60, 70, 80, 90, 100, 110], 110, kind=kind), result # out of bounds for (kind, score, result) in [('rank', 200, 100.0), ('mean', 200, 100.0), ('mean', 0, 0.0)]: yield assert_equal, \ pcos([10, 20, 30, 50, 60, 70, 80, 90, 100, 110], score, kind=kind), result assert_raises(ValueError, pcos, [1, 2, 3, 3, 4], 3, kind='unrecognized') PowerDivCase = namedtuple('Case', ['f_obs', 'f_exp', 'ddof', 'axis', 'chi2', # Pearson's 'log', # G-test (log-likelihood) 'mod_log', # Modified log-likelihood 'cr', # Cressie-Read (lambda=2/3) ]) # The details of the first two elements in power_div_1d_cases are used # in a test in TestPowerDivergence. Check that code before making # any changes here. power_div_1d_cases = [ # Use the default f_exp. PowerDivCase(f_obs=[4, 8, 12, 8], f_exp=None, ddof=0, axis=None, chi2=4, log=2*(4*np.log(4/8) + 12*np.log(12/8)), mod_log=2*(8*np.log(8/4) + 8*np.log(8/12)), cr=(4*((4/8)**(2/3) - 1) + 12*((12/8)**(2/3) - 1))/(5/9)), # Give a non-uniform f_exp. PowerDivCase(f_obs=[4, 8, 12, 8], f_exp=[2, 16, 12, 2], ddof=0, axis=None, chi2=24, log=2*(4*np.log(4/2) + 8*np.log(8/16) + 8*np.log(8/2)), mod_log=2*(2*np.log(2/4) + 16*np.log(16/8) + 2*np.log(2/8)), cr=(4*((4/2)**(2/3) - 1) + 8*((8/16)**(2/3) - 1) + 8*((8/2)**(2/3) - 1))/(5/9)), # f_exp is a scalar. PowerDivCase(f_obs=[4, 8, 12, 8], f_exp=8, ddof=0, axis=None, chi2=4, log=2*(4*np.log(4/8) + 12*np.log(12/8)), mod_log=2*(8*np.log(8/4) + 8*np.log(8/12)), cr=(4*((4/8)**(2/3) - 1) + 12*((12/8)**(2/3) - 1))/(5/9)), # f_exp equal to f_obs. PowerDivCase(f_obs=[3, 5, 7, 9], f_exp=[3, 5, 7, 9], ddof=0, axis=0, chi2=0, log=0, mod_log=0, cr=0), ] power_div_empty_cases = [ # Shape is (0,)--a data set with length 0. The computed # test statistic should be 0. PowerDivCase(f_obs=[], f_exp=None, ddof=0, axis=0, chi2=0, log=0, mod_log=0, cr=0), # Shape is (0, 3). This is 3 data sets, but each data set has # length 0, so the computed test statistic should be [0, 0, 0]. PowerDivCase(f_obs=np.array([[],[],[]]).T, f_exp=None, ddof=0, axis=0, chi2=[0, 0, 0], log=[0, 0, 0], mod_log=[0, 0, 0], cr=[0, 0, 0]), # Shape is (3, 0). This represents an empty collection of # data sets in which each data set has length 3. The test # statistic should be an empty array. PowerDivCase(f_obs=np.array([[],[],[]]), f_exp=None, ddof=0, axis=0, chi2=[], log=[], mod_log=[], cr=[]), ] class TestPowerDivergence(object): def check_power_divergence(self, f_obs, f_exp, ddof, axis, lambda_, expected_stat): f_obs = np.asarray(f_obs) if axis is None: num_obs = f_obs.size else: b = np.broadcast(f_obs, f_exp) num_obs = b.shape[axis] stat, p = stats.power_divergence(f_obs=f_obs, f_exp=f_exp, ddof=ddof, axis=axis, lambda_=lambda_) assert_allclose(stat, expected_stat) if lambda_ == 1 or lambda_ == "pearson": # Also test stats.chisquare. stat, p = stats.chisquare(f_obs=f_obs, f_exp=f_exp, ddof=ddof, axis=axis) assert_allclose(stat, expected_stat) ddof = np.asarray(ddof) expected_p = stats.chisqprob(expected_stat, num_obs - 1 - ddof) assert_allclose(p, expected_p) def test_basic(self): for case in power_div_1d_cases: yield (self.check_power_divergence, case.f_obs, case.f_exp, case.ddof, case.axis, None, case.chi2) yield (self.check_power_divergence, case.f_obs, case.f_exp, case.ddof, case.axis, "pearson", case.chi2) yield (self.check_power_divergence, case.f_obs, case.f_exp, case.ddof, case.axis, 1, case.chi2) yield (self.check_power_divergence, case.f_obs, case.f_exp, case.ddof, case.axis, "log-likelihood", case.log) yield (self.check_power_divergence, case.f_obs, case.f_exp, case.ddof, case.axis, "mod-log-likelihood", case.mod_log) yield (self.check_power_divergence, case.f_obs, case.f_exp, case.ddof, case.axis, "cressie-read", case.cr) yield (self.check_power_divergence, case.f_obs, case.f_exp, case.ddof, case.axis, 2/3, case.cr) def test_basic_masked(self): for case in power_div_1d_cases: mobs = np.ma.array(case.f_obs) yield (self.check_power_divergence, mobs, case.f_exp, case.ddof, case.axis, None, case.chi2) yield (self.check_power_divergence, mobs, case.f_exp, case.ddof, case.axis, "pearson", case.chi2) yield (self.check_power_divergence, mobs, case.f_exp, case.ddof, case.axis, 1, case.chi2) yield (self.check_power_divergence, mobs, case.f_exp, case.ddof, case.axis, "log-likelihood", case.log) yield (self.check_power_divergence, mobs, case.f_exp, case.ddof, case.axis, "mod-log-likelihood", case.mod_log) yield (self.check_power_divergence, mobs, case.f_exp, case.ddof, case.axis, "cressie-read", case.cr) yield (self.check_power_divergence, mobs, case.f_exp, case.ddof, case.axis, 2/3, case.cr) def test_axis(self): case0 = power_div_1d_cases[0] case1 = power_div_1d_cases[1] f_obs = np.vstack((case0.f_obs, case1.f_obs)) f_exp = np.vstack((np.ones_like(case0.f_obs)*np.mean(case0.f_obs), case1.f_exp)) # Check the four computational code paths in power_divergence # using a 2D array with axis=1. yield (self.check_power_divergence, f_obs, f_exp, 0, 1, "pearson", [case0.chi2, case1.chi2]) yield (self.check_power_divergence, f_obs, f_exp, 0, 1, "log-likelihood", [case0.log, case1.log]) yield (self.check_power_divergence, f_obs, f_exp, 0, 1, "mod-log-likelihood", [case0.mod_log, case1.mod_log]) yield (self.check_power_divergence, f_obs, f_exp, 0, 1, "cressie-read", [case0.cr, case1.cr]) # Reshape case0.f_obs to shape (2,2), and use axis=None. # The result should be the same. yield (self.check_power_divergence, np.array(case0.f_obs).reshape(2, 2), None, 0, None, "pearson", case0.chi2) def test_ddof_broadcasting(self): # Test that ddof broadcasts correctly. # ddof does not affect the test statistic. It is broadcast # with the computed test statistic for the computation of # the p value. case0 = power_div_1d_cases[0] case1 = power_div_1d_cases[1] # Create 4x2 arrays of observed and expected frequencies. f_obs = np.vstack((case0.f_obs, case1.f_obs)).T f_exp = np.vstack((np.ones_like(case0.f_obs)*np.mean(case0.f_obs), case1.f_exp)).T expected_chi2 = [case0.chi2, case1.chi2] # ddof has shape (2, 1). This is broadcast with the computed # statistic, so p will have shape (2,2). ddof = np.array([[0], [1]]) stat, p = stats.power_divergence(f_obs, f_exp, ddof=ddof) assert_allclose(stat, expected_chi2) # Compute the p values separately, passing in scalars for ddof. stat0, p0 = stats.power_divergence(f_obs, f_exp, ddof=ddof[0,0]) stat1, p1 = stats.power_divergence(f_obs, f_exp, ddof=ddof[1,0]) assert_array_equal(p, np.vstack((p0, p1))) def test_empty_cases(self): with warnings.catch_warnings(): warnings.simplefilter("ignore", RuntimeWarning) for case in power_div_empty_cases: yield (self.check_power_divergence, case.f_obs, case.f_exp, case.ddof, case.axis, "pearson", case.chi2) yield (self.check_power_divergence, case.f_obs, case.f_exp, case.ddof, case.axis, "log-likelihood", case.log) yield (self.check_power_divergence, case.f_obs, case.f_exp, case.ddof, case.axis, "mod-log-likelihood", case.mod_log) yield (self.check_power_divergence, case.f_obs, case.f_exp, case.ddof, case.axis, "cressie-read", case.cr) def test_chisquare_masked_arrays(): # Test masked arrays. obs = np.array([[8, 8, 16, 32, -1], [-1, -1, 3, 4, 5]]).T mask = np.array([[0, 0, 0, 0, 1], [1, 1, 0, 0, 0]]).T mobs = np.ma.masked_array(obs, mask) expected_chisq = np.array([24.0, 0.5]) expected_g = np.array([2*(2*8*np.log(0.5) + 32*np.log(2.0)), 2*(3*np.log(0.75) + 5*np.log(1.25))]) chisq, p = stats.chisquare(mobs) mat.assert_array_equal(chisq, expected_chisq) mat.assert_array_almost_equal(p, stats.chisqprob(expected_chisq, mobs.count(axis=0) - 1)) g, p = stats.power_divergence(mobs, lambda_='log-likelihood') mat.assert_array_almost_equal(g, expected_g, decimal=15) mat.assert_array_almost_equal(p, stats.chisqprob(expected_g, mobs.count(axis=0) - 1)) chisq, p = stats.chisquare(mobs.T, axis=1) mat.assert_array_equal(chisq, expected_chisq) mat.assert_array_almost_equal(p, stats.chisqprob(expected_chisq, mobs.T.count(axis=1) - 1)) g, p = stats.power_divergence(mobs.T, axis=1, lambda_="log-likelihood") mat.assert_array_almost_equal(g, expected_g, decimal=15) mat.assert_array_almost_equal(p, stats.chisqprob(expected_g, mobs.count(axis=0) - 1)) obs1 = np.ma.array([3, 5, 6, 99, 10], mask=[0, 0, 0, 1, 0]) exp1 = np.ma.array([2, 4, 8, 10, 99], mask=[0, 0, 0, 0, 1]) chi2, p = stats.chisquare(obs1, f_exp=exp1) # Because of the mask at index 3 of obs1 and at index 4 of exp1, # only the first three elements are included in the calculation # of the statistic. mat.assert_array_equal(chi2, 1/2 + 1/4 + 4/8) # When axis=None, the two values should have type np.float64. chisq, p = stats.chisquare(np.ma.array([1,2,3]), axis=None) assert_(isinstance(chisq, np.float64)) assert_(isinstance(p, np.float64)) assert_equal(chisq, 1.0) assert_almost_equal(p, stats.chisqprob(1.0, 2)) # Empty arrays: # A data set with length 0 returns a masked scalar. with np.errstate(invalid='ignore'): chisq, p = stats.chisquare(np.ma.array([])) assert_(isinstance(chisq, np.ma.MaskedArray)) assert_equal(chisq.shape, ()) assert_(chisq.mask) empty3 = np.ma.array([[],[],[]]) # empty3 is a collection of 0 data sets (whose lengths would be 3, if # there were any), so the return value is an array with length 0. chisq, p = stats.chisquare(empty3) assert_(isinstance(chisq, np.ma.MaskedArray)) mat.assert_array_equal(chisq, []) # empty3.T is an array containing 3 data sets, each with length 0, # so an array of size (3,) is returned, with all values masked. with np.errstate(invalid='ignore'): chisq, p = stats.chisquare(empty3.T) assert_(isinstance(chisq, np.ma.MaskedArray)) assert_equal(chisq.shape, (3,)) assert_(np.all(chisq.mask)) def test_power_divergence_against_cressie_read_data(): # Test stats.power_divergence against tables 4 and 5 from # Cressie and Read, "Multimonial Goodness-of-Fit Tests", # J. R. Statist. Soc. B (1984), Vol 46, No. 3, pp. 440-464. # This tests the calculation for several values of lambda. # `table4` holds just the second and third columns from Table 4. table4 = np.array([ # observed, expected, 15, 15.171, 11, 13.952, 14, 12.831, 17, 11.800, 5, 10.852, 11, 9.9796, 10, 9.1777, 4, 8.4402, 8, 7.7620, 10, 7.1383, 7, 6.5647, 9, 6.0371, 11, 5.5520, 3, 5.1059, 6, 4.6956, 1, 4.3183, 1, 3.9713, 4, 3.6522, ]).reshape(-1, 2) table5 = np.array([ # lambda, statistic -10.0, 72.2e3, -5.0, 28.9e1, -3.0, 65.6, -2.0, 40.6, -1.5, 34.0, -1.0, 29.5, -0.5, 26.5, 0.0, 24.6, 0.5, 23.4, 0.67, 23.1, 1.0, 22.7, 1.5, 22.6, 2.0, 22.9, 3.0, 24.8, 5.0, 35.5, 10.0, 21.4e1, ]).reshape(-1, 2) for lambda_, expected_stat in table5: stat, p = stats.power_divergence(table4[:,0], table4[:,1], lambda_=lambda_) assert_allclose(stat, expected_stat, rtol=5e-3) def test_friedmanchisquare(): # see ticket:113 # verified with matlab and R # From Demsar "Statistical Comparisons of Classifiers over Multiple Data Sets" # 2006, Xf=9.28 (no tie handling, tie corrected Xf >=9.28) x1 = [array([0.763, 0.599, 0.954, 0.628, 0.882, 0.936, 0.661, 0.583, 0.775, 1.0, 0.94, 0.619, 0.972, 0.957]), array([0.768, 0.591, 0.971, 0.661, 0.888, 0.931, 0.668, 0.583, 0.838, 1.0, 0.962, 0.666, 0.981, 0.978]), array([0.771, 0.590, 0.968, 0.654, 0.886, 0.916, 0.609, 0.563, 0.866, 1.0, 0.965, 0.614, 0.9751, 0.946]), array([0.798, 0.569, 0.967, 0.657, 0.898, 0.931, 0.685, 0.625, 0.875, 1.0, 0.962, 0.669, 0.975, 0.970])] # From "Bioestadistica para las ciencias de la salud" Xf=18.95 p<0.001: x2 = [array([4,3,5,3,5,3,2,5,4,4,4,3]), array([2,2,1,2,3,1,2,3,2,1,1,3]), array([2,4,3,3,4,3,3,4,4,1,2,1]), array([3,5,4,3,4,4,3,3,3,4,4,4])] # From Jerrorl H. Zar, "Biostatistical Analysis"(example 12.6), Xf=10.68, 0.005 < p < 0.01: # Probability from this example is inexact using Chisquare aproximation of Friedman Chisquare. x3 = [array([7.0,9.9,8.5,5.1,10.3]), array([5.3,5.7,4.7,3.5,7.7]), array([4.9,7.6,5.5,2.8,8.4]), array([8.8,8.9,8.1,3.3,9.1])] assert_array_almost_equal(stats.friedmanchisquare(x1[0],x1[1],x1[2],x1[3]), (10.2283464566929, 0.0167215803284414)) assert_array_almost_equal(stats.friedmanchisquare(x2[0],x2[1],x2[2],x2[3]), (18.9428571428571, 0.000280938375189499)) assert_array_almost_equal(stats.friedmanchisquare(x3[0],x3[1],x3[2],x3[3]), (10.68, 0.0135882729582176)) np.testing.assert_raises(ValueError, stats.friedmanchisquare,x3[0],x3[1]) # test using mstats assert_array_almost_equal(stats.mstats.friedmanchisquare(x1[0],x1[1],x1[2],x1[3]), (10.2283464566929, 0.0167215803284414)) # the following fails # assert_array_almost_equal(stats.mstats.friedmanchisquare(x2[0],x2[1],x2[2],x2[3]), # (18.9428571428571, 0.000280938375189499)) assert_array_almost_equal(stats.mstats.friedmanchisquare(x3[0],x3[1],x3[2],x3[3]), (10.68, 0.0135882729582176)) np.testing.assert_raises(ValueError,stats.mstats.friedmanchisquare,x3[0],x3[1]) def test_kstest(): # from numpy.testing import assert_almost_equal # comparing with values from R x = np.linspace(-1,1,9) D,p = stats.kstest(x,'norm') assert_almost_equal(D, 0.15865525393145705, 12) assert_almost_equal(p, 0.95164069201518386, 1) x = np.linspace(-15,15,9) D,p = stats.kstest(x,'norm') assert_almost_equal(D, 0.44435602715924361, 15) assert_almost_equal(p, 0.038850140086788665, 8) # the following tests rely on deterministicaly replicated rvs np.random.seed(987654321) x = stats.norm.rvs(loc=0.2, size=100) D,p = stats.kstest(x, 'norm', mode='asymp') assert_almost_equal(D, 0.12464329735846891, 15) assert_almost_equal(p, 0.089444888711820769, 15) assert_almost_equal(np.array(stats.kstest(x, 'norm', mode='asymp')), np.array((0.12464329735846891, 0.089444888711820769)), 15) assert_almost_equal(np.array(stats.kstest(x,'norm', alternative='less')), np.array((0.12464329735846891, 0.040989164077641749)), 15) # this 'greater' test fails with precision of decimal=14 assert_almost_equal(np.array(stats.kstest(x,'norm', alternative='greater')), np.array((0.0072115233216310994, 0.98531158590396228)), 12) # missing: no test that uses *args def test_ks_2samp(): # exact small sample solution data1 = np.array([1.0,2.0]) data2 = np.array([1.0,2.0,3.0]) assert_almost_equal(np.array(stats.ks_2samp(data1+0.01,data2)), np.array((0.33333333333333337, 0.99062316386915694))) assert_almost_equal(np.array(stats.ks_2samp(data1-0.01,data2)), np.array((0.66666666666666674, 0.42490954988801982))) # these can also be verified graphically assert_almost_equal( np.array(stats.ks_2samp(np.linspace(1,100,100), np.linspace(1,100,100)+2+0.1)), np.array((0.030000000000000027, 0.99999999996005062))) assert_almost_equal( np.array(stats.ks_2samp(np.linspace(1,100,100), np.linspace(1,100,100)+2-0.1)), np.array((0.020000000000000018, 0.99999999999999933))) # these are just regression tests assert_almost_equal( np.array(stats.ks_2samp(np.linspace(1,100,100), np.linspace(1,100,110)+20.1)), np.array((0.21090909090909091, 0.015880386730710221))) assert_almost_equal( np.array(stats.ks_2samp(np.linspace(1,100,100), np.linspace(1,100,110)+20-0.1)), np.array((0.20818181818181825, 0.017981441789762638))) def test_ttest_rel(): # regression test tr,pr = 0.81248591389165692, 0.41846234511362157 tpr = ([tr,-tr],[pr,pr]) rvs1 = np.linspace(1,100,100) rvs2 = np.linspace(1.01,99.989,100) rvs1_2D = np.array([np.linspace(1,100,100), np.linspace(1.01,99.989,100)]) rvs2_2D = np.array([np.linspace(1.01,99.989,100), np.linspace(1,100,100)]) t,p = stats.ttest_rel(rvs1, rvs2, axis=0) assert_array_almost_equal([t,p],(tr,pr)) t,p = stats.ttest_rel(rvs1_2D.T, rvs2_2D.T, axis=0) assert_array_almost_equal([t,p],tpr) t,p = stats.ttest_rel(rvs1_2D, rvs2_2D, axis=1) assert_array_almost_equal([t,p],tpr) # test on 3 dimensions rvs1_3D = np.dstack([rvs1_2D,rvs1_2D,rvs1_2D]) rvs2_3D = np.dstack([rvs2_2D,rvs2_2D,rvs2_2D]) t,p = stats.ttest_rel(rvs1_3D, rvs2_3D, axis=1) assert_array_almost_equal(np.abs(t), tr) assert_array_almost_equal(np.abs(p), pr) assert_equal(t.shape, (2, 3)) t,p = stats.ttest_rel(np.rollaxis(rvs1_3D,2), np.rollaxis(rvs2_3D,2), axis=2) assert_array_almost_equal(np.abs(t), tr) assert_array_almost_equal(np.abs(p), pr) assert_equal(t.shape, (3, 2)) olderr = np.seterr(all='ignore') try: # test zero division problem t,p = stats.ttest_rel([0,0,0],[1,1,1]) assert_equal((np.abs(t),p), (np.inf, 0)) assert_equal(stats.ttest_rel([0,0,0], [0,0,0]), (np.nan, np.nan)) # check that nan in input array result in nan output anan = np.array([[1,np.nan],[-1,1]]) assert_equal(stats.ttest_ind(anan, np.zeros((2,2))),([0, np.nan], [1,np.nan])) finally: np.seterr(**olderr) # test incorrect input shape raise an error x = np.arange(24) assert_raises(ValueError, stats.ttest_rel, x.reshape((8, 3)), x.reshape((2, 3, 4))) def test_ttest_ind(): # regression test tr = 1.0912746897927283 pr = 0.27647818616351882 tpr = ([tr,-tr],[pr,pr]) rvs2 = np.linspace(1,100,100) rvs1 = np.linspace(5,105,100) rvs1_2D = np.array([rvs1, rvs2]) rvs2_2D = np.array([rvs2, rvs1]) t,p = stats.ttest_ind(rvs1, rvs2, axis=0) assert_array_almost_equal([t,p],(tr,pr)) t,p = stats.ttest_ind(rvs1_2D.T, rvs2_2D.T, axis=0) assert_array_almost_equal([t,p],tpr) t,p = stats.ttest_ind(rvs1_2D, rvs2_2D, axis=1) assert_array_almost_equal([t,p],tpr) # test on 3 dimensions rvs1_3D = np.dstack([rvs1_2D,rvs1_2D,rvs1_2D]) rvs2_3D = np.dstack([rvs2_2D,rvs2_2D,rvs2_2D]) t,p = stats.ttest_ind(rvs1_3D, rvs2_3D, axis=1) assert_almost_equal(np.abs(t), np.abs(tr)) assert_array_almost_equal(np.abs(p), pr) assert_equal(t.shape, (2, 3)) t,p = stats.ttest_ind(np.rollaxis(rvs1_3D,2), np.rollaxis(rvs2_3D,2), axis=2) assert_array_almost_equal(np.abs(t), np.abs(tr)) assert_array_almost_equal(np.abs(p), pr) assert_equal(t.shape, (3, 2)) olderr = np.seterr(all='ignore') try: # test zero division problem t,p = stats.ttest_ind([0,0,0],[1,1,1]) assert_equal((np.abs(t),p), (np.inf, 0)) assert_equal(stats.ttest_ind([0,0,0], [0,0,0]), (np.nan, np.nan)) # check that nan in input array result in nan output anan = np.array([[1,np.nan],[-1,1]]) assert_equal(stats.ttest_ind(anan, np.zeros((2,2))),([0, np.nan], [1,np.nan])) finally: np.seterr(**olderr) def test_ttest_ind_with_uneq_var(): # check vs. R a = (1, 2, 3) b = (1.1, 2.9, 4.2) pr = 0.53619490753126731 tr = -0.68649512735572582 t, p = stats.ttest_ind(a, b, equal_var=False) assert_array_almost_equal([t,p], [tr, pr]) a = (1, 2, 3, 4) pr = 0.84354139131608286 tr = -0.2108663315950719 t, p = stats.ttest_ind(a, b, equal_var=False) assert_array_almost_equal([t,p], [tr, pr]) # regression test tr = 1.0912746897927283 tr_uneq_n = 0.66745638708050492 pr = 0.27647831993021388 pr_uneq_n = 0.50873585065616544 tpr = ([tr,-tr],[pr,pr]) rvs3 = np.linspace(1,100, 25) rvs2 = np.linspace(1,100,100) rvs1 = np.linspace(5,105,100) rvs1_2D = np.array([rvs1, rvs2]) rvs2_2D = np.array([rvs2, rvs1]) t,p = stats.ttest_ind(rvs1, rvs2, axis=0, equal_var=False) assert_array_almost_equal([t,p],(tr,pr)) t,p = stats.ttest_ind(rvs1, rvs3, axis=0, equal_var=False) assert_array_almost_equal([t,p], (tr_uneq_n, pr_uneq_n)) t,p = stats.ttest_ind(rvs1_2D.T, rvs2_2D.T, axis=0, equal_var=False) assert_array_almost_equal([t,p],tpr) t,p = stats.ttest_ind(rvs1_2D, rvs2_2D, axis=1, equal_var=False) assert_array_almost_equal([t,p],tpr) # test on 3 dimensions rvs1_3D = np.dstack([rvs1_2D,rvs1_2D,rvs1_2D]) rvs2_3D = np.dstack([rvs2_2D,rvs2_2D,rvs2_2D]) t,p = stats.ttest_ind(rvs1_3D, rvs2_3D, axis=1, equal_var=False) assert_almost_equal(np.abs(t), np.abs(tr)) assert_array_almost_equal(np.abs(p), pr) assert_equal(t.shape, (2, 3)) t,p = stats.ttest_ind(np.rollaxis(rvs1_3D,2), np.rollaxis(rvs2_3D,2), axis=2, equal_var=False) assert_array_almost_equal(np.abs(t), np.abs(tr)) assert_array_almost_equal(np.abs(p), pr) assert_equal(t.shape, (3, 2)) olderr = np.seterr(all='ignore') try: # test zero division problem t,p = stats.ttest_ind([0,0,0],[1,1,1], equal_var=False) assert_equal((np.abs(t),p), (np.inf, 0)) assert_equal(stats.ttest_ind([0,0,0], [0,0,0], equal_var=False), (np.nan, np.nan)) # check that nan in input array result in nan output anan = np.array([[1,np.nan],[-1,1]]) assert_equal(stats.ttest_ind(anan, np.zeros((2,2)), equal_var=False), ([0, np.nan], [1,np.nan])) finally: np.seterr(**olderr) def test_ttest_1samp_new(): n1, n2, n3 = (10,15,20) rvn1 = stats.norm.rvs(loc=5,scale=10,size=(n1,n2,n3)) # check multidimensional array and correct axis handling # deterministic rvn1 and rvn2 would be better as in test_ttest_rel t1,p1 = stats.ttest_1samp(rvn1[:,:,:], np.ones((n2,n3)),axis=0) t2,p2 = stats.ttest_1samp(rvn1[:,:,:], 1,axis=0) t3,p3 = stats.ttest_1samp(rvn1[:,0,0], 1) assert_array_almost_equal(t1,t2, decimal=14) assert_almost_equal(t1[0,0],t3, decimal=14) assert_equal(t1.shape, (n2,n3)) t1,p1 = stats.ttest_1samp(rvn1[:,:,:], np.ones((n1,n3)),axis=1) t2,p2 = stats.ttest_1samp(rvn1[:,:,:], 1,axis=1) t3,p3 = stats.ttest_1samp(rvn1[0,:,0], 1) assert_array_almost_equal(t1,t2, decimal=14) assert_almost_equal(t1[0,0],t3, decimal=14) assert_equal(t1.shape, (n1,n3)) t1,p1 = stats.ttest_1samp(rvn1[:,:,:], np.ones((n1,n2)),axis=2) t2,p2 = stats.ttest_1samp(rvn1[:,:,:], 1,axis=2) t3,p3 = stats.ttest_1samp(rvn1[0,0,:], 1) assert_array_almost_equal(t1,t2, decimal=14) assert_almost_equal(t1[0,0],t3, decimal=14) assert_equal(t1.shape, (n1,n2)) olderr = np.seterr(all='ignore') try: # test zero division problem t,p = stats.ttest_1samp([0,0,0], 1) assert_equal((np.abs(t),p), (np.inf, 0)) assert_equal(stats.ttest_1samp([0,0,0], 0), (np.nan, np.nan)) # check that nan in input array result in nan output anan = np.array([[1,np.nan],[-1,1]]) assert_equal(stats.ttest_1samp(anan, 0),([0, np.nan], [1,np.nan])) finally: np.seterr(**olderr) def test_describe(): x = np.vstack((np.ones((3,4)),2*np.ones((2,4)))) nc, mmc = (5, ([1., 1., 1., 1.], [2., 2., 2., 2.])) mc = np.array([1.4, 1.4, 1.4, 1.4]) vc = np.array([0.3, 0.3, 0.3, 0.3]) skc = [0.40824829046386357]*4 kurtc = [-1.833333333333333]*4 n, mm, m, v, sk, kurt = stats.describe(x) assert_equal(n, nc) assert_equal(mm, mmc) assert_equal(m, mc) assert_equal(v, vc) assert_array_almost_equal(sk, skc, decimal=13) # not sure about precision assert_array_almost_equal(kurt, kurtc, decimal=13) n, mm, m, v, sk, kurt = stats.describe(x.T, axis=1) assert_equal(n, nc) assert_equal(mm, mmc) assert_equal(m, mc) assert_equal(v, vc) assert_array_almost_equal(sk, skc, decimal=13) # not sure about precision assert_array_almost_equal(kurt, kurtc, decimal=13) def test_normalitytests(): # numbers verified with R: dagoTest in package fBasics st_normal, st_skew, st_kurt = (3.92371918, 1.98078826, -0.01403734) pv_normal, pv_skew, pv_kurt = (0.14059673, 0.04761502, 0.98880019) x = np.array((-2,-1,0,1,2,3)*4)**2 yield assert_array_almost_equal, stats.normaltest(x), (st_normal, pv_normal) yield assert_array_almost_equal, stats.skewtest(x), (st_skew, pv_skew) yield assert_array_almost_equal, stats.kurtosistest(x), (st_kurt, pv_kurt) # Test axis=None (equal to axis=0 for 1-D input) yield (assert_array_almost_equal, stats.normaltest(x, axis=None), (st_normal, pv_normal)) yield (assert_array_almost_equal, stats.skewtest(x, axis=None), (st_skew, pv_skew)) yield (assert_array_almost_equal, stats.kurtosistest(x, axis=None), (st_kurt, pv_kurt)) class TestJarqueBera(TestCase): def test_jarque_bera_stats(self): np.random.seed(987654321) x = np.random.normal(0, 1, 100000) y = np.random.chisquare(10000, 100000) z = np.random.rayleigh(1, 100000) assert_(stats.jarque_bera(x)[1] > stats.jarque_bera(y)[1]) assert_(stats.jarque_bera(x)[1] > stats.jarque_bera(z)[1]) assert_(stats.jarque_bera(y)[1] > stats.jarque_bera(z)[1]) def test_jarque_bera_array_like(self): np.random.seed(987654321) x = np.random.normal(0, 1, 100000) JB1, p1 = stats.jarque_bera(list(x)) JB2, p2 = stats.jarque_bera(tuple(x)) JB3, p3 = stats.jarque_bera(x.reshape(2, 50000)) assert_(JB1 == JB2 == JB3) assert_(p1 == p2 == p3) def test_jarque_bera_size(self): assert_raises(ValueError, stats.jarque_bera, []) def test_skewtest_too_few_samples(): # Regression test for ticket #1492. # skewtest requires at least 8 samples; 7 should raise a ValueError. x = np.arange(7.0) assert_raises(ValueError, stats.skewtest, x) def test_kurtosistest_too_few_samples(): # Regression test for ticket #1425. # kurtosistest requires at least 5 samples; 4 should raise a ValueError. x = np.arange(4.0) assert_raises(ValueError, stats.kurtosistest, x) def test_mannwhitneyu(): x = np.array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 2., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 2., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 2., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 2., 1., 1., 1., 1., 2., 1., 1., 2., 1., 1., 2., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 2., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 2., 1., 1., 1., 1., 1., 1., 1., 1., 1., 2., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 3., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]) y = np.array([1., 1., 1., 1., 1., 1., 1., 2., 1., 2., 1., 1., 1., 1., 2., 1., 1., 1., 2., 1., 1., 1., 1., 1., 2., 1., 1., 3., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 2., 1., 2., 1., 1., 1., 1., 1., 1., 2., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 2., 1., 1., 1., 1., 1., 2., 2., 1., 1., 2., 1., 1., 2., 1., 2., 1., 1., 1., 1., 2., 2., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 2., 1., 1., 1., 1., 1., 2., 2., 2., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 2., 1., 1., 2., 1., 1., 1., 1., 2., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 2., 1., 1., 1., 2., 1., 1., 1., 1., 1., 1.]) # p-value verified with matlab and R to 5 significant digits assert_array_almost_equal(stats.stats.mannwhitneyu(x,y), (16980.5, 2.8214327656317373e-005), decimal=12) def test_pointbiserial(): # same as mstats test except for the nan # Test data: http://support.sas.com/ctx/samples/index.jsp?sid=490&tab=output x = [1,0,1,1,1,1,0,1,0,0,0,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,0, 0,0,0,0,1] y = [14.8,13.8,12.4,10.1,7.1,6.1,5.8,4.6,4.3,3.5,3.3,3.2,3.0, 2.8,2.8,2.5,2.4,2.3,2.1,1.7,1.7,1.5,1.3,1.3,1.2,1.2,1.1, 0.8,0.7,0.6,0.5,0.2,0.2,0.1] assert_almost_equal(stats.pointbiserialr(x, y)[0], 0.36149, 5) def test_obrientransform(): # A couple tests calculated by hand. x1 = np.array([0, 2, 4]) t1 = stats.obrientransform(x1) expected = [7, -2, 7] assert_allclose(t1[0], expected) x2 = np.array([0, 3, 6, 9]) t2 = stats.obrientransform(x2) expected = np.array([30, 0, 0, 30]) assert_allclose(t2[0], expected) # Test two arguments. a, b = stats.obrientransform(x1, x2) assert_equal(a, t1[0]) assert_equal(b, t2[0]) # Test three arguments. a, b, c = stats.obrientransform(x1, x2, x1) assert_equal(a, t1[0]) assert_equal(b, t2[0]) assert_equal(c, t1[0]) # This is a regression test to check np.var replacement. # The author of this test didn't separately verify the numbers. x1 = np.arange(5) result = np.array( [[5.41666667, 1.04166667, -0.41666667, 1.04166667, 5.41666667], [21.66666667, 4.16666667, -1.66666667, 4.16666667, 21.66666667]]) assert_array_almost_equal(stats.obrientransform(x1, 2*x1), result, decimal=8) # Example from "O'Brien Test for Homogeneity of Variance" # by Herve Abdi. values = range(5, 11) reps = np.array([5, 11, 9, 3, 2, 2]) data = np.repeat(values, reps) transformed_values = np.array([3.1828, 0.5591, 0.0344, 1.6086, 5.2817, 11.0538]) expected = np.repeat(transformed_values, reps) result = stats.obrientransform(data) assert_array_almost_equal(result[0], expected, decimal=4) class HarMeanTestCase: def test_1dlist(self): # Test a 1d list a = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100] b = 34.1417152147 self.do(a, b) def test_1darray(self): # Test a 1d array a = np.array([10, 20, 30, 40, 50, 60, 70, 80, 90, 100]) b = 34.1417152147 self.do(a, b) def test_1dma(self): # Test a 1d masked array a = np.ma.array([10, 20, 30, 40, 50, 60, 70, 80, 90, 100]) b = 34.1417152147 self.do(a, b) def test_1dmavalue(self): # Test a 1d masked array with a masked value a = np.ma.array([10, 20, 30, 40, 50, 60, 70, 80, 90, 100], mask=[0,0,0,0,0,0,0,0,0,1]) b = 31.8137186141 self.do(a, b) # Note the next tests use axis=None as default, not axis=0 def test_2dlist(self): # Test a 2d list a = [[10, 20, 30, 40], [50, 60, 70, 80], [90, 100, 110, 120]] b = 38.6696271841 self.do(a, b) def test_2darray(self): # Test a 2d array a = [[10, 20, 30, 40], [50, 60, 70, 80], [90, 100, 110, 120]] b = 38.6696271841 self.do(np.array(a), b) def test_2dma(self): # Test a 2d masked array a = [[10, 20, 30, 40], [50, 60, 70, 80], [90, 100, 110, 120]] b = 38.6696271841 self.do(np.ma.array(a), b) def test_2daxis0(self): # Test a 2d list with axis=0 a = [[10, 20, 30, 40], [50, 60, 70, 80], [90, 100, 110, 120]] b = np.array([22.88135593, 39.13043478, 52.90076336, 65.45454545]) self.do(a, b, axis=0) def test_2daxis1(self): # Test a 2d list with axis=1 a = [[10, 20, 30, 40], [50, 60, 70, 80], [90, 100, 110, 120]] b = np.array([19.2, 63.03939962, 103.80078637]) self.do(a, b, axis=1) def test_2dmatrixdaxis0(self): # Test a 2d list with axis=0 a = [[10, 20, 30, 40], [50, 60, 70, 80], [90, 100, 110, 120]] b = np.matrix([[22.88135593, 39.13043478, 52.90076336, 65.45454545]]) self.do(np.matrix(a), b, axis=0) def test_2dmatrixaxis1(self): # Test a 2d list with axis=1 a = [[10, 20, 30, 40], [50, 60, 70, 80], [90, 100, 110, 120]] b = np.matrix([[19.2, 63.03939962, 103.80078637]]).T self.do(np.matrix(a), b, axis=1) class TestHarMean(HarMeanTestCase, TestCase): def do(self, a, b, axis=None, dtype=None): x = stats.hmean(a, axis=axis, dtype=dtype) assert_almost_equal(b, x) assert_equal(x.dtype, dtype) class GeoMeanTestCase: def test_1dlist(self): # Test a 1d list a = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100] b = 45.2872868812 self.do(a, b) def test_1darray(self): # Test a 1d array a = np.array([10, 20, 30, 40, 50, 60, 70, 80, 90, 100]) b = 45.2872868812 self.do(a, b) def test_1dma(self): # Test a 1d masked array a = np.ma.array([10, 20, 30, 40, 50, 60, 70, 80, 90, 100]) b = 45.2872868812 self.do(a, b) def test_1dmavalue(self): # Test a 1d masked array with a masked value a = np.ma.array([10, 20, 30, 40, 50, 60, 70, 80, 90, 100], mask=[0,0,0,0,0,0,0,0,0,1]) b = 41.4716627439 self.do(a, b) # Note the next tests use axis=None as default, not axis=0 def test_2dlist(self): # Test a 2d list a = [[10, 20, 30, 40], [50, 60, 70, 80], [90, 100, 110, 120]] b = 52.8885199 self.do(a, b) def test_2darray(self): # Test a 2d array a = [[10, 20, 30, 40], [50, 60, 70, 80], [90, 100, 110, 120]] b = 52.8885199 self.do(np.array(a), b) def test_2dma(self): # Test a 2d masked array a = [[10, 20, 30, 40], [50, 60, 70, 80], [90, 100, 110, 120]] b = 52.8885199 self.do(np.ma.array(a), b) def test_2daxis0(self): # Test a 2d list with axis=0 a = [[10, 20, 30, 40], [50, 60, 70, 80], [90, 100, 110, 120]] b = np.array([35.56893304, 49.32424149, 61.3579244, 72.68482371]) self.do(a, b, axis=0) def test_2daxis1(self): # Test a 2d list with axis=1 a = [[10, 20, 30, 40], [50, 60, 70, 80], [90, 100, 110, 120]] b = np.array([22.13363839, 64.02171746, 104.40086817]) self.do(a, b, axis=1) def test_2dmatrixdaxis0(self): # Test a 2d list with axis=0 a = [[10, 20, 30, 40], [50, 60, 70, 80], [90, 100, 110, 120]] b = np.matrix([[35.56893304, 49.32424149, 61.3579244, 72.68482371]]) self.do(np.matrix(a), b, axis=0) def test_2dmatrixaxis1(self): # Test a 2d list with axis=1 a = [[10, 20, 30, 40], [50, 60, 70, 80], [90, 100, 110, 120]] b = np.matrix([[22.13363839, 64.02171746, 104.40086817]]).T self.do(np.matrix(a), b, axis=1) def test_1dlist0(self): # Test a 1d list with zero element a = [10, 20, 30, 40, 50, 60, 70, 80, 90, 0] b = 0.0 # due to exp(-inf)=0 olderr = np.seterr(all='ignore') try: self.do(a, b) finally: np.seterr(**olderr) def test_1darray0(self): # Test a 1d array with zero element a = np.array([10, 20, 30, 40, 50, 60, 70, 80, 90, 0]) b = 0.0 # due to exp(-inf)=0 olderr = np.seterr(all='ignore') try: self.do(a, b) finally: np.seterr(**olderr) def test_1dma0(self): # Test a 1d masked array with zero element a = np.ma.array([10, 20, 30, 40, 50, 60, 70, 80, 90, 0]) b = 41.4716627439 olderr = np.seterr(all='ignore') try: self.do(a, b) finally: np.seterr(**olderr) def test_1dmainf(self): # Test a 1d masked array with negative element a = np.ma.array([10, 20, 30, 40, 50, 60, 70, 80, 90, -1]) b = 41.4716627439 olderr = np.seterr(all='ignore') try: self.do(a, b) finally: np.seterr(**olderr) class TestGeoMean(GeoMeanTestCase, TestCase): def do(self, a, b, axis=None, dtype=None): # Note this doesn't test when axis is not specified x = stats.gmean(a, axis=axis, dtype=dtype) assert_almost_equal(b, x) assert_equal(x.dtype, dtype) def test_binomtest(): # precision tests compared to R for ticket:986 pp = np.concatenate((np.linspace(0.1,0.2,5), np.linspace(0.45,0.65,5), np.linspace(0.85,0.95,5))) n = 501 x = 450 results = [0.0, 0.0, 1.0159969301994141e-304, 2.9752418572150531e-275, 7.7668382922535275e-250, 2.3381250925167094e-099, 7.8284591587323951e-081, 9.9155947819961383e-065, 2.8729390725176308e-050, 1.7175066298388421e-037, 0.0021070691951093692, 0.12044570587262322, 0.88154763174802508, 0.027120993063129286, 2.6102587134694721e-006] for p, res in zip(pp,results): assert_approx_equal(stats.binom_test(x, n, p), res, significant=12, err_msg='fail forp=%f' % p) assert_approx_equal(stats.binom_test(50,100,0.1), 5.8320387857343647e-024, significant=12, err_msg='fail forp=%f' % p) def test_binomtest2(): # test added for issue #2384 res2 = [ [1.0, 1.0], [0.5,1.0,0.5], [0.25,1.00,1.00,0.25], [0.125,0.625,1.000,0.625,0.125], [0.0625,0.3750,1.0000,1.0000,0.3750,0.0625], [0.03125,0.21875,0.68750,1.00000,0.68750,0.21875,0.03125], [0.015625,0.125000,0.453125,1.000000,1.000000,0.453125,0.125000,0.015625], [0.0078125,0.0703125,0.2890625,0.7265625,1.0000000,0.7265625,0.2890625, 0.0703125,0.0078125], [0.00390625,0.03906250,0.17968750,0.50781250,1.00000000,1.00000000, 0.50781250,0.17968750,0.03906250,0.00390625], [0.001953125,0.021484375,0.109375000,0.343750000,0.753906250,1.000000000, 0.753906250,0.343750000,0.109375000,0.021484375,0.001953125] ] for k in range(1, 11): res1 = [stats.binom_test(v, k, 0.5) for v in range(k + 1)] assert_almost_equal(res1, res2[k-1], decimal=10) def test_binomtest3(): # test added for issue #2384 # test when x == n*p and neighbors res3 = [stats.binom_test(v, v*k, 1./k) for v in range(1, 11) for k in range(2, 11)] assert_equal(res3, np.ones(len(res3), int)) #> bt=c() #> for(i in as.single(1:10)){for(k in as.single(2:10)){bt = c(bt, binom.test(i-1, k*i,(1/k))$p.value); print(c(i+1, k*i,(1/k)))}} binom_testm1 = np.array([ 0.5, 0.5555555555555556, 0.578125, 0.5904000000000003, 0.5981224279835393, 0.603430543396034, 0.607304096221924, 0.610255656871054, 0.612579511000001, 0.625, 0.670781893004115, 0.68853759765625, 0.6980101120000006, 0.703906431368616, 0.70793209416498, 0.7108561134173507, 0.713076544331419, 0.714820192935702, 0.6875, 0.7268709038256367, 0.7418963909149174, 0.74986110468096, 0.7548015520398076, 0.7581671424768577, 0.760607984787832, 0.762459425024199, 0.7639120677676575, 0.7265625, 0.761553963657302, 0.774800934828818, 0.7818005980538996, 0.78613491480358, 0.789084353140195, 0.7912217659828884, 0.79284214559524, 0.794112956558801, 0.75390625, 0.7856929451142176, 0.7976688481430754, 0.8039848974727624, 0.807891868948366, 0.8105487660137676, 0.812473307174702, 0.8139318233591120, 0.815075399104785, 0.7744140625, 0.8037322594985427, 0.814742863657656, 0.8205425178645808, 0.8241275984172285, 0.8265645374416, 0.8283292196088257, 0.829666291102775, 0.8307144686362666, 0.7905273437499996, 0.8178712053954738, 0.828116983756619, 0.833508948940494, 0.8368403871552892, 0.839104213210105, 0.840743186196171, 0.84198481438049, 0.8429580531563676, 0.803619384765625, 0.829338573944648, 0.8389591907548646, 0.84401876783902, 0.84714369697889, 0.8492667010581667, 0.850803474598719, 0.851967542858308, 0.8528799045949524, 0.8145294189453126, 0.838881732845347, 0.847979024541911, 0.852760894015685, 0.8557134656773457, 0.8577190131799202, 0.85917058278431, 0.860270010472127, 0.861131648404582, 0.823802947998047, 0.846984756807511, 0.855635653643743, 0.860180994825685, 0.86298688573253, 0.864892525675245, 0.866271647085603, 0.867316125625004, 0.8681346531755114 ]) # > bt=c() # > for(i in as.single(1:10)){for(k in as.single(2:10)){bt = c(bt, binom.test(i+1, k*i,(1/k))$p.value); print(c(i+1, k*i,(1/k)))}} binom_testp1 = np.array([ 0.5, 0.259259259259259, 0.26171875, 0.26272, 0.2632244513031551, 0.2635138663069203, 0.2636951804161073, 0.2638162407564354, 0.2639010709000002, 0.625, 0.4074074074074074, 0.42156982421875, 0.4295746560000003, 0.43473045988554, 0.4383309503172684, 0.4409884859402103, 0.4430309389962837, 0.444649849401104, 0.6875, 0.4927602499618962, 0.5096031427383425, 0.5189636628480, 0.5249280070771274, 0.5290623300865124, 0.5320974248125793, 0.5344204730474308, 0.536255847400756, 0.7265625, 0.5496019313526808, 0.5669248746708034, 0.576436455045805, 0.5824538812831795, 0.5866053321547824, 0.589642781414643, 0.5919618019300193, 0.593790427805202, 0.75390625, 0.590868349763505, 0.607983393277209, 0.617303847446822, 0.623172512167948, 0.627208862156123, 0.6301556891501057, 0.632401894928977, 0.6341708982290303, 0.7744140625, 0.622562037497196, 0.639236102912278, 0.648263335014579, 0.65392850011132, 0.657816519817211, 0.660650782947676, 0.662808780346311, 0.6645068560246006, 0.7905273437499996, 0.6478843304312477, 0.6640468318879372, 0.6727589686071775, 0.6782129857784873, 0.681950188903695, 0.684671508668418, 0.686741824999918, 0.688369886732168, 0.803619384765625, 0.668716055304315, 0.684360013879534, 0.6927642396829181, 0.6980155964704895, 0.701609591890657, 0.7042244320992127, 0.7062125081341817, 0.707775152962577, 0.8145294189453126, 0.686243374488305, 0.7013873696358975, 0.709501223328243, 0.714563595144314, 0.718024953392931, 0.7205416252126137, 0.722454130389843, 0.723956813292035, 0.823802947998047, 0.701255953767043, 0.715928221686075, 0.723772209289768, 0.7286603031173616, 0.7319999279787631, 0.7344267920995765, 0.736270323773157, 0.737718376096348 ]) res4_p1 = [stats.binom_test(v+1, v*k, 1./k) for v in range(1, 11) for k in range(2, 11)] res4_m1 = [stats.binom_test(v-1, v*k, 1./k) for v in range(1, 11) for k in range(2, 11)] assert_almost_equal(res4_p1, binom_testp1, decimal=13) assert_almost_equal(res4_m1, binom_testm1, decimal=13) class TestTrim(object): # test trim functions def test_trim1(self): a = np.arange(11) assert_equal(stats.trim1(a, 0.1), np.arange(10)) assert_equal(stats.trim1(a, 0.2), np.arange(9)) assert_equal(stats.trim1(a, 0.2, tail='left'), np.arange(2,11)) assert_equal(stats.trim1(a, 3/11., tail='left'), np.arange(3,11)) def test_trimboth(self): a = np.arange(11) assert_equal(stats.trimboth(a, 3/11.), np.arange(3,8)) assert_equal(stats.trimboth(a, 0.2), np.array([2, 3, 4, 5, 6, 7, 8])) assert_equal(stats.trimboth(np.arange(24).reshape(6,4), 0.2), np.arange(4,20).reshape(4,4)) assert_equal(stats.trimboth(np.arange(24).reshape(4,6).T, 2/6.), np.array([[2, 8, 14, 20],[3, 9, 15, 21]])) assert_raises(ValueError, stats.trimboth, np.arange(24).reshape(4,6).T, 4/6.) def test_trim_mean(self): # don't use pre-sorted arrays a = np.array([4, 8, 2, 0, 9, 5, 10, 1, 7, 3, 6]) idx = np.array([3, 5, 0, 1, 2, 4]) a2 = np.arange(24).reshape(6, 4)[idx, :] a3 = np.arange(24).reshape(6, 4, order='F')[idx, :] assert_equal(stats.trim_mean(a3, 2/6.), np.array([2.5, 8.5, 14.5, 20.5])) assert_equal(stats.trim_mean(a2, 2/6.), np.array([10., 11., 12., 13.])) idx4 = np.array([1, 0, 3, 2]) a4 = np.arange(24).reshape(4, 6)[idx4, :] assert_equal(stats.trim_mean(a4, 2/6.), np.array([9., 10., 11., 12., 13., 14.])) # shuffled arange(24) as array_like a = [7, 11, 12, 21, 16, 6, 22, 1, 5, 0, 18, 10, 17, 9, 19, 15, 23, 20, 2, 14, 4, 13, 8, 3] assert_equal(stats.trim_mean(a, 2/6.), 11.5) assert_equal(stats.trim_mean([5,4,3,1,2,0], 2/6.), 2.5) # check axis argument np.random.seed(1234) a = np.random.randint(20, size=(5, 6, 4, 7)) for axis in [0, 1, 2, 3, -1]: res1 = stats.trim_mean(a, 2/6., axis=axis) res2 = stats.trim_mean(np.rollaxis(a, axis), 2/6.) assert_equal(res1, res2) res1 = stats.trim_mean(a, 2/6., axis=None) res2 = stats.trim_mean(a.ravel(), 2/6.) assert_equal(res1, res2) assert_raises(ValueError, stats.trim_mean, a, 0.6) class TestSigamClip(object): def test_sigmaclip1(self): a = np.concatenate((np.linspace(9.5,10.5,31),np.linspace(0,20,5))) fact = 4 # default c, low, upp = stats.sigmaclip(a) assert_(c.min() > low) assert_(c.max() < upp) assert_equal(low, c.mean() - fact*c.std()) assert_equal(upp, c.mean() + fact*c.std()) assert_equal(c.size, a.size) def test_sigmaclip2(self): a = np.concatenate((np.linspace(9.5,10.5,31),np.linspace(0,20,5))) fact = 1.5 c, low, upp = stats.sigmaclip(a, fact, fact) assert_(c.min() > low) assert_(c.max() < upp) assert_equal(low, c.mean() - fact*c.std()) assert_equal(upp, c.mean() + fact*c.std()) assert_equal(c.size, 4) assert_equal(a.size, 36) # check original array unchanged def test_sigmaclip3(self): a = np.concatenate((np.linspace(9.5,10.5,11),np.linspace(-100,-50,3))) fact = 1.8 c, low, upp = stats.sigmaclip(a, fact, fact) assert_(c.min() > low) assert_(c.max() < upp) assert_equal(low, c.mean() - fact*c.std()) assert_equal(upp, c.mean() + fact*c.std()) assert_equal(c, np.linspace(9.5,10.5,11)) class TestFOneWay(TestCase): def test_trivial(self): # A trivial test of stats.f_oneway, with F=0. F, p = stats.f_oneway([0,2], [0,2]) assert_equal(F, 0.0) def test_basic(self): # Despite being a floating point calculation, this data should # result in F being exactly 2.0. F, p = stats.f_oneway([0,2], [2,4]) assert_equal(F, 2.0) def test_large_integer_array(self): a = np.array([655, 788], dtype=np.uint16) b = np.array([789, 772], dtype=np.uint16) F, p = stats.f_oneway(a, b) assert_almost_equal(F, 0.77450216931805538) class TestKruskal(TestCase): def test_simple(self): x = [1] y = [2] h, p = stats.kruskal(x, y) assert_equal(h, 1.0) assert_approx_equal(p, stats.chisqprob(h, 1)) h, p = stats.kruskal(np.array(x), np.array(y)) assert_equal(h, 1.0) assert_approx_equal(p, stats.chisqprob(h, 1)) def test_basic(self): x = [1, 3, 5, 7, 9] y = [2, 4, 6, 8, 10] h, p = stats.kruskal(x, y) assert_approx_equal(h, 3./11, significant=10) assert_approx_equal(p, stats.chisqprob(3./11, 1)) h, p = stats.kruskal(np.array(x), np.array(y)) assert_approx_equal(h, 3./11, significant=10) assert_approx_equal(p, stats.chisqprob(3./11, 1)) def test_simple_tie(self): x = [1] y = [1, 2] h_uncorr = 1.5**2 + 2*2.25**2 - 12 corr = 0.75 expected = h_uncorr / corr # 0.5 h, p = stats.kruskal(x, y) # Since the expression is simple and the exact answer is 0.5, it # should be safe to use assert_equal(). assert_equal(h, expected) def test_another_tie(self): x = [1, 1, 1, 2] y = [2, 2, 2, 2] h_uncorr = (12. / 8. / 9.) * 4 * (3**2 + 6**2) - 3 * 9 corr = 1 - float(3**3 - 3 + 5**3 - 5) / (8**3 - 8) expected = h_uncorr / corr h, p = stats.kruskal(x, y) assert_approx_equal(h, expected) def test_three_groups(self): # A test of stats.kruskal with three groups, with ties. x = [1, 1, 1] y = [2, 2, 2] z = [2, 2] h_uncorr = (12. / 8. / 9.) * (3*2**2 + 3*6**2 + 2*6**2) - 3 * 9 # 5.0 corr = 1 - float(3**3 - 3 + 5**3 - 5) / (8**3 - 8) expected = h_uncorr / corr # 7.0 h, p = stats.kruskal(x, y, z) assert_approx_equal(h, expected) assert_approx_equal(p, stats.chisqprob(h, 2)) if __name__ == "__main__": run_module_suite()