diff options
author | Jonathan Helmus <jjhelmus@gmail.com> | 2013-09-05 11:20:56 -0500 |
---|---|---|
committer | Jonathan Helmus <jjhelmus@gmail.com> | 2013-09-13 17:03:37 -0500 |
commit | 4a084a0d77bbb7ade065e75d3602fd8b47369d76 (patch) | |
tree | 9a40376fc97924019eabaf2406cec9fcdc3620fd | |
parent | 07cbe999f84be4d1b0a35fdb15b53cc17bc4341d (diff) | |
download | numpy-4a084a0d77bbb7ade065e75d3602fd8b47369d76.tar.gz |
MAINT: cleaning up percentile function.
-rw-r--r-- | numpy/lib/function_base.py | 24 | ||||
-rw-r--r-- | numpy/lib/tests/test_function_base.py | 49 |
2 files changed, 21 insertions, 52 deletions
diff --git a/numpy/lib/function_base.py b/numpy/lib/function_base.py index 55d104740..48a86dff0 100644 --- a/numpy/lib/function_base.py +++ b/numpy/lib/function_base.py @@ -2767,8 +2767,8 @@ def median(a, axis=None, out=None, overwrite_input=False): return mean(part[indexer], axis=axis, out=out) -def percentile(a, q, limit=None, interpolation='linear', axis=None, - out=None, overwrite_input=False): +def percentile(a, q, interpolation='linear', axis=None, out=None, + overwrite_input=False): """ Compute the qth percentile of the data along the specified axis. @@ -2780,17 +2780,15 @@ def percentile(a, q, limit=None, interpolation='linear', axis=None, Input array or object that can be converted to an array. q : float in range of [0,100] (or sequence of floats) Percentile to compute which must be between 0 and 100 inclusive. - limit : tuple, optional - Tuple of two scalars, the lower and upper limits within which to - compute the percentile. Values outside of this range are ommitted from - the percentile calculation. None includes all values in calculation. - interpolation : {'linear', 'lower', 'higher', 'midpoint'}, optional + interpolation : {'linear', 'lower', 'higher', 'midpoint', 'closest'} This optional parameter specifies the interpolation method to use, when the desired quantile lies between two data points `i` and `j`: * linear: `i + (j - i) * fraction`, where `fraction` is the fractional part of the index surrounded by `i` and `j`. * lower: `i`. * higher: `j`. + * closest: `i` or `j` whichever is closest. + * midpoint: (`i` + `j`) / 2. axis : int, optional Axis along which the percentiles are computed. The default (None) is to compute the percentiles along a flattened version of the array. @@ -2860,10 +2858,6 @@ def percentile(a, q, limit=None, interpolation='linear', axis=None, """ a = asarray(a) - - if limit: # filter a based on limits - a = a[(limit[0] <= a) & (a <= limit[1])] - q = atleast_1d(q) q = q / 100.0 if (q < 0).any() or (q > 1).any(): @@ -2892,14 +2886,18 @@ def percentile(a, q, limit=None, interpolation='linear', axis=None, indices = floor(indices).astype(intp) elif interpolation == 'higher': indices = ceil(indices).astype(intp) + elif interpolation == 'midpoint': + indices = floor(indices) + 0.5 + elif interpolation == 'closest': + indices = around(indices).astype(intp) elif interpolation == 'linear': pass # keep index as fraction and interpolate else: raise ValueError("interpolation can only be 'linear', 'lower' " - "or 'higher'") + "'higher', 'midpoint', or 'closest'") if indices.dtype == intp: # take the points along axis - ap.partition(indices.copy(), axis=axis) + ap.partition(indices, axis=axis) return take(ap, indices, axis=axis, out=out) else: # weight the points above and below the indices indices_below = floor(indices).astype(intp) diff --git a/numpy/lib/tests/test_function_base.py b/numpy/lib/tests/test_function_base.py index 02597c78b..f0512420e 100644 --- a/numpy/lib/tests/test_function_base.py +++ b/numpy/lib/tests/test_function_base.py @@ -1456,37 +1456,14 @@ class TestScoreatpercentile(TestCase): [1, 1, 1]]) assert_array_equal(np.percentile(x, 50, axis=0), [[1, 1, 1]]) - def test_limit(self): - x = np.arange(10) - assert_equal(np.percentile(x, 50, limit=(2, 5)), 3.5) - assert_equal(np.percentile([2, 3, 4, 5], 50), 3.5) - - assert_equal(np.percentile(x, 50, limit=(-1, 8)), 4) - assert_equal(np.percentile([0, 1, 2, 3, 4, 5, 6, 7, 8], 50), 4) - - assert_equal(np.percentile(x, 50, limit=(4, 11)), 6.5) - assert_equal(np.percentile([4, 5, 6, 7, 8, 9], 50, ), 6.5) - def test_linear(self): # Test defaults assert_equal(np.percentile(range(10), 50), 4.5) - assert_equal(np.percentile(range(10), 50, (2, 7)), 4.5) - assert_equal(np.percentile(range(100), 50, limit=(1, 8)), 4.5) - assert_equal(np.percentile(np.array([1, 10, 100]), 50, (10, 100)), 55) - assert_equal(np.percentile(np.array([1, 10, 100]), 50, (1, 10)), 5.5) # explicitly specify interpolation_method 'fraction' (the default) assert_equal(np.percentile(range(10), 50, interpolation='linear'), 4.5) - assert_equal(np.percentile(range(10), 50, limit=(2, 7), - interpolation='linear'), 4.5) - assert_equal(np.percentile(range(100), 50, limit=(1, 8), - interpolation='linear'), 4.5) - assert_equal(np.percentile(np.array([1, 10, 100]), 50, (10, 100), - interpolation='linear'), 55) - assert_equal(np.percentile(np.array([1, 10, 100]), 50, (1, 10), - interpolation='linear'), 5.5) def test_lower_higher(self): @@ -1495,22 +1472,16 @@ class TestScoreatpercentile(TestCase): interpolation='lower'), 4) assert_equal(np.percentile(range(10), 50, interpolation='higher'), 5) - assert_equal(np.percentile(range(10), 50, (2, 7), - interpolation='lower'), 4) - assert_equal(np.percentile(range(10), 50, limit=(2, 7), - interpolation='higher'), 5) - assert_equal(np.percentile(range(100), 50, (1, 8), - interpolation='lower'), 4) - assert_equal(np.percentile(range(100), 50, (1, 8), - interpolation='higher'), 5) - assert_equal(np.percentile(np.array([1, 10, 100]), 50, (10, 100), - interpolation='lower'), 10) - assert_equal(np.percentile(np.array([1, 10, 100]), 50, limit=(10, 100), - interpolation='higher'), 100) - assert_equal(np.percentile(np.array([1, 10, 100]), 50, (1, 10), - interpolation='lower'), 1) - assert_equal(np.percentile(np.array([1, 10, 100]), 50, limit=(1, 10), - interpolation='higher'), 10) + + def test_midpoint(self): + assert_equal(np.percentile(range(10), 51, + interpolation='midpoint'), 4.5) + + def test_closest(self): + assert_equal(np.percentile(range(10), 51, + interpolation='closest'), 5) + assert_equal(np.percentile(range(10), 49, + interpolation='closest'), 4) def test_sequence(self): x = np.arange(8) * 0.5 |