From cf1689dedfcb02314515f4f68d1d6d117c19cce1 Mon Sep 17 00:00:00 2001 From: Amit Aronovitch Date: Sun, 1 May 2016 00:17:23 +0300 Subject: [PATCH 1/2] test that ma.median of 1d array returns a scalar --- numpy/ma/tests/test_extras.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/numpy/ma/tests/test_extras.py b/numpy/ma/tests/test_extras.py index 52669cb909ee..b2c053fbd1bd 100644 --- a/numpy/ma/tests/test_extras.py +++ b/numpy/ma/tests/test_extras.py @@ -662,6 +662,19 @@ def test_non_masked(self): assert_equal(np.ma.median(np.arange(9)), 4.) assert_equal(np.ma.median(range(9)), 4) + def test_masked_1d(self): + "test the examples given in the docstring of ma.median" + x = array(np.arange(8), mask=[0]*4 + [1]*4) + assert_equal(np.ma.median(x), 1.5) + assert_equal(np.ma.median(x).shape, (), "shape mismatch") + x = array(np.arange(10).reshape(2, 5), mask=[0]*6 + [1]*4) + assert_equal(np.ma.median(x), 2.5) + assert_equal(np.ma.median(x).shape, (), "shape mismatch") + + def test_1d_shape_consistency(self): + assert_equal(np.ma.median(array([1,2,3],mask=[0,0,0])).shape, + np.ma.median(array([1,2,3],mask=[0,1,0])).shape ) + def test_2d(self): # Tests median w/ 2D (n, p) = (101, 30) From 51887f48d06a0d1101007866734c579f6eb3bf5e Mon Sep 17 00:00:00 2001 From: Amit Aronovitch Date: Sun, 1 May 2016 00:20:12 +0300 Subject: [PATCH 2/2] ma.median: fix 1d behavior: avoid triggering advanced indexing's special case for list of scalars --- numpy/ma/extras.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/numpy/ma/extras.py b/numpy/ma/extras.py index ea8f9e49af03..4f288fb26a12 100644 --- a/numpy/ma/extras.py +++ b/numpy/ma/extras.py @@ -654,19 +654,21 @@ def _median(a, axis=None, out=None, overwrite_input=False): axis += a.ndim counts = asorted.shape[axis] - (asorted.mask).sum(axis=axis) - h = counts // 2 + h = np.asarray(counts // 2) # create indexing mesh grid for all but reduced axis axes_grid = [np.arange(x) for i, x in enumerate(asorted.shape) if i != axis] ind = np.meshgrid(*axes_grid, sparse=True, indexing='ij') # insert indices of low and high median ind.insert(axis, h - 1) + ind[axis] = np.asarray(h-1) low = asorted[ind] - low._sharedmask = False + if hasattr(low,"mask"): + low._sharedmask = False ind[axis] = h high = asorted[ind] # duplicate high if odd number of elements so mean does nothing - odd = counts % 2 == 1 + odd = np.asarray( counts % 2 == 1 ) if asorted.ndim == 1: if odd: low = high @@ -676,7 +678,10 @@ def _median(a, axis=None, out=None, overwrite_input=False): if np.issubdtype(asorted.dtype, np.inexact): # avoid inf / x = masked s = np.ma.sum([low, high], axis=0, out=out) - np.true_divide(s.data, 2., casting='unsafe', out=s.data) + if hasattr(s,"mask"): + np.true_divide(s.data, 2., casting='unsafe', out=s.data) + else: + s = np.true_divide(s,2.0) else: s = np.ma.mean([low, high], axis=0, out=out) return s