Revision: 8039
          http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8039&view=rev
Author:   astraw
Date:     2009-12-18 22:25:26 +0000 (Fri, 18 Dec 2009)

Log Message:
-----------
bugfix: mlab.prctile handles even-length data

Modified Paths:
--------------
    trunk/matplotlib/CHANGELOG
    trunk/matplotlib/lib/matplotlib/mlab.py

Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG  2009-12-18 22:25:16 UTC (rev 8038)
+++ trunk/matplotlib/CHANGELOG  2009-12-18 22:25:26 UTC (rev 8039)
@@ -1,3 +1,6 @@
+2009-12-18 mlab.prctile handles even-length data, such that the median
+           is the mean of the two middle values. - ADS
+
 2009-12-15 Add raw-image (unsampled) support for the ps backend. - JJL
 
 2009-12-14 Add patch_artist kwarg to boxplot, but keep old default.

Modified: trunk/matplotlib/lib/matplotlib/mlab.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/mlab.py     2009-12-18 22:25:16 UTC (rev 
8038)
+++ trunk/matplotlib/lib/matplotlib/mlab.py     2009-12-18 22:25:26 UTC (rev 
8039)
@@ -904,19 +904,39 @@
     the *p* percentage point in the sequence is returned.
     """
 
+    # This implementation derived from scipy.stats.scoreatpercentile
+    def _interpolate(a, b, fraction):
+        """Returns the point at the given fraction between a and b, where
+        'fraction' must be between 0 and 1.
+        """
+        return a + (b - a)*fraction
 
-    x = np.array(x).ravel()  # we need a copy
-    x.sort()
-    Nx = len(x)
+    scalar = True
+    if cbook.iterable(p):
+        scalar = False
+    per = np.array(p)
+    values = np.array(x).ravel()  # copy
+    values.sort()
 
-    if not cbook.iterable(p):
-        return x[int(p*Nx/100.0)]
+    idxs = per /100. * (values.shape[0] - 1)
+    ai = idxs.astype(np.int)
+    bi = ai + 1
+    frac = idxs % 1
 
-    p = np.asarray(p)* Nx/100.0
-    ind = p.astype(int)
-    ind = np.where(ind>=Nx, Nx-1, ind)
-    return x.take(ind)
+    # handle cases where attempting to interpolate past last index
+    cond = bi >= len(values)
+    if scalar:
+        if cond:
+            ai -= 1
+            bi -= 1
+            frac += 1
+    else:
+        ai[cond] -= 1
+        bi[cond] -= 1
+        frac[cond] += 1
 
+    return _interpolate(values[ai],values[bi],frac)
+
 def prctile_rank(x, p):
     """
     Return the rank for each element in *x*, return the rank


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev 
_______________________________________________
Matplotlib-checkins mailing list
Matplotlib-checkins@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins

Reply via email to