diff options
author | Sebastian Berg <sebastian@sipsolutions.net> | 2016-06-19 14:01:47 +0200 |
---|---|---|
committer | Sebastian Berg <sebastian@sipsolutions.net> | 2016-09-02 10:10:55 +0200 |
commit | c1ddf841f6a48248b946a990ae750505b8b91686 (patch) | |
tree | 8eb8ee586515c9a2df78f241fe01b9e1ba2bfc3f /numpy | |
parent | 78d7cc4f3422826954b067a5b030f0807f85f294 (diff) | |
download | numpy-c1ddf841f6a48248b946a990ae750505b8b91686.tar.gz |
ENH: Remove warning ignoring from nanfuncs
Comment mentions a speedup, but it seems unsure why it should
be there. Instead use an error state in divide_by_count.
Some extra complex warnings had to be ignored (but those seemed correct)
Diffstat (limited to 'numpy')
-rw-r--r-- | numpy/lib/nanfunctions.py | 72 | ||||
-rw-r--r-- | numpy/lib/tests/test_nanfunctions.py | 62 | ||||
-rw-r--r-- | numpy/lib/tests/test_twodim_base.py | 2 |
3 files changed, 66 insertions, 70 deletions
diff --git a/numpy/lib/nanfunctions.py b/numpy/lib/nanfunctions.py index 9d3640647..c2fc92ebf 100644 --- a/numpy/lib/nanfunctions.py +++ b/numpy/lib/nanfunctions.py @@ -130,7 +130,7 @@ def _divide_by_count(a, b, out=None): in place. If `a` is a numpy scalar, the division preserves its type. """ - with np.errstate(invalid='ignore'): + with np.errstate(invalid='ignore', divide='ignore'): if isinstance(a, np.ndarray): if out is None: return np.divide(a, b, out=a, casting='unsafe') @@ -815,12 +815,9 @@ def nanmean(a, axis=None, dtype=None, out=None, keepdims=np._NoValue): if out is not None and not issubclass(out.dtype.type, np.inexact): raise TypeError("If a is inexact, then out must be inexact") - # The warning context speeds things up. - with warnings.catch_warnings(): - warnings.simplefilter('ignore') - cnt = np.sum(~mask, axis=axis, dtype=np.intp, keepdims=keepdims) - tot = np.sum(arr, axis=axis, dtype=dtype, out=out, keepdims=keepdims) - avg = _divide_by_count(tot, cnt, out=out) + cnt = np.sum(~mask, axis=axis, dtype=np.intp, keepdims=keepdims) + tot = np.sum(arr, axis=axis, dtype=dtype, out=out, keepdims=keepdims) + avg = _divide_by_count(tot, cnt, out=out) isbad = (cnt == 0) if isbad.any(): @@ -1288,38 +1285,35 @@ def nanvar(a, axis=None, dtype=None, out=None, ddof=0, keepdims=np._NoValue): if out is not None and not issubclass(out.dtype.type, np.inexact): raise TypeError("If a is inexact, then out must be inexact") - with warnings.catch_warnings(): - warnings.simplefilter('ignore') - - # Compute mean - if type(arr) is np.matrix: - _keepdims = np._NoValue - else: - _keepdims = True - # we need to special case matrix for reverse compatibility - # in order for this to work, these sums need to be called with - # keepdims=True, however matrix now raises an error in this case, but - # the reason that it drops the keepdims kwarg is to force keepdims=True - # so this used to work by serendipity. - cnt = np.sum(~mask, axis=axis, dtype=np.intp, keepdims=_keepdims) - avg = np.sum(arr, axis=axis, dtype=dtype, keepdims=_keepdims) - avg = _divide_by_count(avg, cnt) - - # Compute squared deviation from mean. - np.subtract(arr, avg, out=arr, casting='unsafe') - arr = _copyto(arr, 0, mask) - if issubclass(arr.dtype.type, np.complexfloating): - sqr = np.multiply(arr, arr.conj(), out=arr).real - else: - sqr = np.multiply(arr, arr, out=arr) - - # Compute variance. - var = np.sum(sqr, axis=axis, dtype=dtype, out=out, keepdims=keepdims) - if var.ndim < cnt.ndim: - # Subclasses of ndarray may ignore keepdims, so check here. - cnt = cnt.squeeze(axis) - dof = cnt - ddof - var = _divide_by_count(var, dof) + # Compute mean + if type(arr) is np.matrix: + _keepdims = np._NoValue + else: + _keepdims = True + # we need to special case matrix for reverse compatibility + # in order for this to work, these sums need to be called with + # keepdims=True, however matrix now raises an error in this case, but + # the reason that it drops the keepdims kwarg is to force keepdims=True + # so this used to work by serendipity. + cnt = np.sum(~mask, axis=axis, dtype=np.intp, keepdims=_keepdims) + avg = np.sum(arr, axis=axis, dtype=dtype, keepdims=_keepdims) + avg = _divide_by_count(avg, cnt) + + # Compute squared deviation from mean. + np.subtract(arr, avg, out=arr, casting='unsafe') + arr = _copyto(arr, 0, mask) + if issubclass(arr.dtype.type, np.complexfloating): + sqr = np.multiply(arr, arr.conj(), out=arr).real + else: + sqr = np.multiply(arr, arr, out=arr) + + # Compute variance. + var = np.sum(sqr, axis=axis, dtype=dtype, out=out, keepdims=keepdims) + if var.ndim < cnt.ndim: + # Subclasses of ndarray may ignore keepdims, so check here. + cnt = cnt.squeeze(axis) + dof = cnt - ddof + var = _divide_by_count(var, dof) isbad = (dof <= 0) if np.any(isbad): diff --git a/numpy/lib/tests/test_nanfunctions.py b/numpy/lib/tests/test_nanfunctions.py index 03f9beff6..e062bc032 100644 --- a/numpy/lib/tests/test_nanfunctions.py +++ b/numpy/lib/tests/test_nanfunctions.py @@ -5,7 +5,7 @@ import warnings import numpy as np from numpy.testing import ( run_module_suite, TestCase, assert_, assert_equal, assert_almost_equal, - assert_warns, assert_no_warnings, assert_raises, assert_array_equal + assert_no_warnings, assert_raises, assert_array_equal, suppress_warnings ) @@ -317,26 +317,30 @@ class SharedNanFunctionsTestsMixin(object): codes = 'efdgFDG' for nf, rf in zip(self.nanfuncs, self.stdfuncs): for c in codes: - tgt = rf(mat, dtype=np.dtype(c), axis=1).dtype.type - res = nf(mat, dtype=np.dtype(c), axis=1).dtype.type - assert_(res is tgt) - # scalar case - tgt = rf(mat, dtype=np.dtype(c), axis=None).dtype.type - res = nf(mat, dtype=np.dtype(c), axis=None).dtype.type - assert_(res is tgt) + with suppress_warnings() as sup: + sup.filter(np.ComplexWarning) + tgt = rf(mat, dtype=np.dtype(c), axis=1).dtype.type + res = nf(mat, dtype=np.dtype(c), axis=1).dtype.type + assert_(res is tgt) + # scalar case + tgt = rf(mat, dtype=np.dtype(c), axis=None).dtype.type + res = nf(mat, dtype=np.dtype(c), axis=None).dtype.type + assert_(res is tgt) def test_dtype_from_char(self): mat = np.eye(3) codes = 'efdgFDG' for nf, rf in zip(self.nanfuncs, self.stdfuncs): for c in codes: - tgt = rf(mat, dtype=c, axis=1).dtype.type - res = nf(mat, dtype=c, axis=1).dtype.type - assert_(res is tgt) - # scalar case - tgt = rf(mat, dtype=c, axis=None).dtype.type - res = nf(mat, dtype=c, axis=None).dtype.type - assert_(res is tgt) + with suppress_warnings() as sup: + sup.filter(np.ComplexWarning) + tgt = rf(mat, dtype=c, axis=1).dtype.type + res = nf(mat, dtype=c, axis=1).dtype.type + assert_(res is tgt) + # scalar case + tgt = rf(mat, dtype=c, axis=None).dtype.type + res = nf(mat, dtype=c, axis=None).dtype.type + assert_(res is tgt) def test_dtype_from_input(self): codes = 'efdgFDG' @@ -524,16 +528,16 @@ class TestNanFunctions_MeanVarStd(TestCase, SharedNanFunctionsTestsMixin): dsize = [len(d) for d in _rdat] for nf, rf in zip(nanfuncs, stdfuncs): for ddof in range(5): - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always') + with suppress_warnings() as sup: + sup.record(RuntimeWarning) + sup.filter(np.ComplexWarning) tgt = [ddof >= d for d in dsize] res = nf(_ndat, axis=1, ddof=ddof) assert_equal(np.isnan(res), tgt) if any(tgt): - assert_(len(w) == 1) - assert_(issubclass(w[0].category, RuntimeWarning)) + assert_(len(sup.log) == 1) else: - assert_(len(w) == 0) + assert_(len(sup.log) == 0) def test_allnans(self): mat = np.array([np.nan]*9).reshape(3, 3) @@ -642,22 +646,20 @@ class TestNanFunctions_Median(TestCase): def test_allnans(self): mat = np.array([np.nan]*9).reshape(3, 3) for axis in [None, 0, 1]: - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always') - warnings.simplefilter('ignore', FutureWarning) + with suppress_warnings() as sup: + sup.record(RuntimeWarning) + assert_(np.isnan(np.nanmedian(mat, axis=axis)).all()) if axis is None: - assert_(len(w) == 1) + assert_(len(sup.log) == 1) else: - assert_(len(w) == 3) - assert_(issubclass(w[0].category, RuntimeWarning)) + assert_(len(sup.log) == 3) # Check scalar assert_(np.isnan(np.nanmedian(np.nan))) if axis is None: - assert_(len(w) == 2) + assert_(len(sup.log) == 2) else: - assert_(len(w) == 4) - assert_(issubclass(w[0].category, RuntimeWarning)) + assert_(len(sup.log) == 4) def test_empty(self): mat = np.zeros((0, 3)) @@ -686,7 +688,7 @@ class TestNanFunctions_Median(TestCase): def test_float_special(self): with warnings.catch_warnings(record=True): - warnings.simplefilter('ignore', RuntimeWarning) + warnings.simplefilter('always', RuntimeWarning) a = np.array([[np.inf, np.nan], [np.nan, np.nan]]) assert_equal(np.nanmedian(a, axis=0), [np.inf, np.nan]) assert_equal(np.nanmedian(a, axis=1), [np.inf, np.nan]) diff --git a/numpy/lib/tests/test_twodim_base.py b/numpy/lib/tests/test_twodim_base.py index 31925d5fe..98b8aa39c 100644 --- a/numpy/lib/tests/test_twodim_base.py +++ b/numpy/lib/tests/test_twodim_base.py @@ -5,7 +5,7 @@ from __future__ import division, absolute_import, print_function from numpy.testing import ( TestCase, run_module_suite, assert_equal, assert_array_equal, - assert_array_max_ulp, assert_array_almost_equal, assert_raises + assert_array_max_ulp, assert_array_almost_equal, assert_raises, ) from numpy import ( |