summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Helmus <jjhelmus@gmail.com>2013-09-05 11:20:56 -0500
committerJonathan Helmus <jjhelmus@gmail.com>2013-09-13 17:03:37 -0500
commit4a084a0d77bbb7ade065e75d3602fd8b47369d76 (patch)
tree9a40376fc97924019eabaf2406cec9fcdc3620fd
parent07cbe999f84be4d1b0a35fdb15b53cc17bc4341d (diff)
downloadnumpy-4a084a0d77bbb7ade065e75d3602fd8b47369d76.tar.gz
MAINT: cleaning up percentile function.
-rw-r--r--numpy/lib/function_base.py24
-rw-r--r--numpy/lib/tests/test_function_base.py49
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