There are several commonly used methods for estimating percentiles (a.k.a. quantiles) based on sample data. For large samples, the different methods agree closely, but when sample sizes are small, different methods will give significantly different results. The algorithm implemented here works as follows:
n be the length of the (sorted) array and
0 < p <= 100 be the desired percentile. n = 1 return the unique array element (regardless of
the value of p); otherwise pos = p * (n + 1) / 100 and the difference, d
between pos and floor(pos) (i.e. the fractional
part of pos).pos < 1 return the smallest element in the array.pos >= n return the largest element in the array.lower be the element in position
floor(pos) in the array and let upper be the
next element in the array. Return lower + d * (upper - lower)
To compute percentiles, the data must be at least partially ordered. Input
arrays are copied and recursively partitioned using an ordering definition.
The ordering used by Arrays.sort(double[]) is the one determined
by java.. This ordering makes
Double.NaN larger than any other value (including
Double.POSITIVE_INFINITY). Therefore, for example, the median
(50th percentile) of
{0, 1, 2, 3, 4, Double.NaN} evaluates to 2.5.
Since percentile estimation usually involves interpolation between array
elements, arrays containing NaN or infinite values will often
result in NaN or infinite values returned.
Further, to include different estimation types such as R1, R2 as mentioned in Quantile page(wikipedia), a type specific NaN handling strategy is used to closely match with the typically observed results from popular tools like R(R1-R9), Excel(R7).
Since 2.2, Percentile uses only selection instead of complete sorting
and caches selection algorithm state between calls to the various
evaluate methods. This greatly improves efficiency, both for a single
percentile and multiple percentile computations. To maximize performance when
multiple percentiles are computed based on the same data, users should set the
data array once using either one of the evaluate(double[], double) or
setData(double[]) methods and thereafter evaluate(double)
with just the percentile provided.
Note that this implementation is not synchronized. If
multiple threads access an instance of this class concurrently, and at least
one of the threads invokes the increment() or
clear() method, it must be synchronized externally.
| Modifier and Type | Class and Description |
|---|---|
| public static enum | Percentile.
An enum for various estimation strategies of a percentile referred in wikipedia on quantile with the names of enum matching those of types mentioned in wikipedia. |
| Modifier and Type | Field and Description |
|---|---|
| private int[] | cachedPivots
Cached pivots. |
| private final Percentile. | estimationType
Any of the |
| private final KthSelector | kthSelector
Default KthSelector used with default pivoting strategy |
| private static final int | MAX_CACHED_LEVELS
Maximum number of partitioning pivots cached (each level double the number of pivots). |
| private final NaNStrategy | nanStrategy
NaN Handling of the input as defined by |
| private static final int | PIVOTS_HEAP_LENGTH
Maximum number of cached pivots in the pivots cached array |
| private double | quantile
Determines what percentile is computed when evaluate() is activated with no quantile argument |
| private static final long | serialVersionUID
Serializable version identifier |
| Access | Constructor and Description |
|---|---|
| public | |
| public | Percentile(final double
the quantile quantile)Constructs a Percentile with the specific quantile value and the following
|
| public | Percentile(final Percentile
the original)Percentile instance to copyCopy constructor, creates a new |
| protected | Percentile(final double
the quantile to be computed quantile, final Percentile.one of the percentile estimationType,estimation typesone of nanStrategy, final KthSelector NaNStrategy to handle with NaNsa kthSelector)KthSelector to use for pivoting during searchConstructs a Percentile with the specific quantile value,
|
| Modifier and Type | Method and Description |
|---|---|
| public Percentile | copy()
Implements abstract org. Implements org. Returns a copy of the statistic with the same internal state. |
| public static void | copy(final Percentile
Percentile to copy source, final Percentile Percentile to copy to dest)
Deprecated
as of 3.4 this method does not work anymore, as it fails to
copy internal states between instances configured with different
estimation type, NaN handling strategies
and kthSelector, it therefore always
throw MathUnsupportedOperationException
Copies source to dest. |
| private static double[] | Returns: copy of a slice of the original arraythe input array values, final int start index of the array to include begin, final int number of elements to include from begin length)Make a copy of the array for the slice defined by array part from [begin, begin+length) |
| public double | Returns: the value of the statistic applied to the stored datathe percentile value to compute p)Returns the result of evaluating the statistic over the stored data. |
| public double | Returns: the percentile value or Double.NaN if the array is emptyinput array of values values, final double the percentile value to compute p)Returns an estimate of the |
| public double | Returns: the percentile valuethe input array values, final int index of the first array element to include start, final int the number of elements to include length)Implements abstract org. Implements org. Returns an estimate of the |
| public double | Returns: the percentile valuearray of input values values, final int the first (0-based) element to include in the computation begin, final int the number of array elements to include length, final double the percentile to compute p)Returns an estimate of the |
| public Percentile. | |
| public KthSelector | |
| public NaNStrategy | Returns: NaN Handling strategy set during constructionGet the |
| public PivotingStrategyInterface | Returns: the pivoting strategy setGet the |
| private int[] | Returns: cached pivots or a newly created onearray containing the input numbers values)Get pivots which is either cached or a newly created one |
| public double | Returns: quantile set while construction orsetQuantile(double)Returns the value of the quantile field (determines what percentile is computed when evaluate() is called with no quantile argument). |
| protected double[] | Returns: work array sliced from values in the range [begin,begin+length)the array of numbers values, final int index to start reading the array begin, final int the length of array to be read from the begin index length)Get the work array to operate. |
| pack-priv int | Returns: the index of the median element chosen between the first, the middle and the last element of the array slicedata array work, final int index of the first element of the slice begin, final int index after the last element of the slice end)
Deprecated
Please refrain from using this method (as it wont take effect)
and instead use
Percentile#withKthSelector(newKthSelector) if
required.
Select a pivot index as the median of three Note With the effect of allowing |
| private static double[] | Returns: the copy of the sliced array after removing the removedValuethe input array values, final int start index of the array to include begin, final int number of elements to include from begin length, final double the value to be removed from the sliced array removedValue)Remove the occurrence of a given value in a copied slice of array defined by the array part from [begin, begin+length). |
| private static double[] | Returns: the copy of sliced array with replaced valuesthe input array values, final int start index of the array to include begin, final int number of elements to include from begin length, final double the value to be replaced with original, final double the value to be used for replacement replacement)Replace every occurrence of a given value with a replacement value in a copied slice of array defined by array part from [begin, begin+length). |
| public void | setData(final double[]
data array to store (may be null to remove stored data) values)Overrides org. Set the data array. |
| public void | setData(final double[]
data array to store values, final int the index of the first element to include begin, final int the number of elements to include length)Overrides org. Set the data array. |
| public void | setQuantile(final double
a value between 0 < p <= 100 p)Sets the value of the quantile field (determines what percentile is computed when evaluate() is called with no quantile argument). |
| public Percentile | Returns: a new instance, with changed estimation typeestimation type for the new instance newEstimationTypeBuild a new instance similar to the current one except for the
|
| public Percentile | Returns: a new instance, with changed KthSelectorKthSelector for the new instance newKthSelector)Build a new instance similar to the current one except for the
|
| public Percentile | Returns: a new instance, with changed NaN handling strategyNaN strategy for the new instance newNaNStrategy)Build a new instance similar to the current one except for the
|
| cachedPivots | back to summary |
|---|---|
| private int[] cachedPivots Cached pivots. | |
| estimationType | back to summary |
|---|---|
| private final Percentile. Any of the | |
| kthSelector | back to summary |
|---|---|
| private final KthSelector kthSelector Default KthSelector used with default pivoting strategy | |
| MAX_CACHED_LEVELS | back to summary |
|---|---|
| private static final int MAX_CACHED_LEVELS Maximum number of partitioning pivots cached (each level double the number of pivots). | |
| nanStrategy | back to summary |
|---|---|
| private final NaNStrategy nanStrategy NaN Handling of the input as defined by | |
| PIVOTS_HEAP_LENGTH | back to summary |
|---|---|
| private static final int PIVOTS_HEAP_LENGTH Maximum number of cached pivots in the pivots cached array | |
| quantile | back to summary |
|---|---|
| private double quantile Determines what percentile is computed when evaluate() is activated with no quantile argument | |
| serialVersionUID | back to summary |
|---|---|
| private static final long serialVersionUID Serializable version identifier | |
| Percentile | back to summary |
|---|---|
| public Percentile() Constructs a Percentile with the following defaults.
| |
| Percentile | back to summary |
|---|---|
| public Percentile(final double quantile) throws MathIllegalArgumentException Constructs a Percentile with the specific quantile value and the following
| |
| Percentile | back to summary |
|---|---|
| public Percentile(final Percentile original) throws NullArgumentException Copy constructor, creates a new
| |
| Percentile | back to summary |
|---|---|
| protected Percentile(final double quantile, final Percentile. Constructs a Percentile with the specific quantile value,
| |
| copy | back to summary |
|---|---|
| public Percentile copy() Implements abstract org. Implements org. Doc from org. Returns a copy of the statistic with the same internal state.
| |
| copy | back to summary |
|---|---|
| public static void copy(final Percentile source, final Percentile dest) throws MathUnsupportedOperationException
Deprecated as of 3.4 this method does not work anymore, as it fails to
copy internal states between instances configured with different
Copies source to dest.
| |
| copyOf | back to summary |
|---|---|
| private static double[] copyOf(final double[] values, final int begin, final int length) Make a copy of the array for the slice defined by array part from [begin, begin+length)
| |
| evaluate | back to summary |
|---|---|
| public double evaluate(final double p) throws MathIllegalArgumentException Returns the result of evaluating the statistic over the stored data.
The stored array is the one which was set by previous calls to
| |
| evaluate | back to summary |
|---|---|
| public double evaluate(final double[] values, final double p) throws MathIllegalArgumentException Returns an estimate of the
Calls to this method do not modify the internal
See
| |
| evaluate | back to summary |
|---|---|
| public double evaluate(final double[] values, final int start, final int length) throws MathIllegalArgumentException Implements abstract org. Implements org. Returns an estimate of the
See
| |
| evaluate | back to summary |
|---|---|
| public double evaluate(final double[] values, final int begin, final int length, final double p) throws MathIllegalArgumentException Returns an estimate of the
Calls to this method do not modify the internal
See
| |
| getEstimationType | back to summary |
|---|---|
| public Percentile. Get the estimation
| |
| getKthSelector | back to summary |
|---|---|
| public KthSelector getKthSelector() Get the
| |
| getNaNStrategy | back to summary |
|---|---|
| public NaNStrategy getNaNStrategy() Get the
| |
| getPivotingStrategy | back to summary |
|---|---|
| public PivotingStrategyInterface getPivotingStrategy() Get the
| |
| getPivots | back to summary |
|---|---|
| private int[] getPivots(final double[] values) Get pivots which is either cached or a newly created one
| |
| getQuantile | back to summary |
|---|---|
| public double getQuantile() Returns the value of the quantile field (determines what percentile is computed when evaluate() is called with no quantile argument).
| |
| getWorkArray | back to summary |
|---|---|
| protected double[] getWorkArray(final double[] values, final int begin, final int length) Get the work array to operate. Makes use of prior
| |
| medianOf3 | back to summary |
|---|---|
| pack-priv int medianOf3(final double[] work, final int begin, final int end)
Deprecated Please refrain from using this method (as it wont take effect)
and instead use Select a pivot index as the median of three Note With the effect of allowing
| |
| removeAndSlice | back to summary |
|---|---|
| private static double[] removeAndSlice(final double[] values, final int begin, final int length, final double removedValue) Remove the occurrence of a given value in a copied slice of array defined by the array part from [begin, begin+length).
| |
| replaceAndSlice | back to summary |
|---|---|
| private static double[] replaceAndSlice(final double[] values, final int begin, final int length, final double original, final double replacement) Replace every occurrence of a given value with a replacement value in a copied slice of array defined by array part from [begin, begin+length).
| |
| setData | back to summary |
|---|---|
| public void setData(final double[] values) Overrides org. Doc from org. Set the data array. The stored value is a copy of the parameter array, not the array itself.
| |
| setData | back to summary |
|---|---|
| public void setData(final double[] values, final int begin, final int length) throws MathIllegalArgumentException Overrides org. Doc from org. Set the data array. The input array is copied, not referenced.
| |
| setQuantile | back to summary |
|---|---|
| public void setQuantile(final double p) throws MathIllegalArgumentException Sets the value of the quantile field (determines what percentile is computed when evaluate() is called with no quantile argument).
| |
| withEstimationType | back to summary |
|---|---|
| public Percentile withEstimationType(final Percentile. Build a new instance similar to the current one except for the
This method is intended to be used as part of a fluent-type builder pattern. Building finely tune instances should be done as follows:
Percentile customized = new Percentile(quantile).
withEstimationType(estimationType).
withNaNStrategy(nanStrategy).
withKthSelector(kthSelector);
If any of the
| |
| withKthSelector | back to summary |
|---|---|
| public Percentile withKthSelector(final KthSelector newKthSelector) Build a new instance similar to the current one except for the
This method is intended to be used as part of a fluent-type builder pattern. Building finely tune instances should be done as follows:
Percentile customized = new Percentile(quantile).
withEstimationType(estimationType).
withNaNStrategy(nanStrategy).
withKthSelector(newKthSelector);
If any of the
| |
| withNaNStrategy | back to summary |
|---|---|
| public Percentile withNaNStrategy(final NaNStrategy newNaNStrategy) Build a new instance similar to the current one except for the
This method is intended to be used as part of a fluent-type builder pattern. Building finely tune instances should be done as follows:
Percentile customized = new Percentile(quantile).
withEstimationType(estimationType).
withNaNStrategy(nanStrategy).
withKthSelector(kthSelector);
If any of the
| |
Each enum corresponding to the specific type of estimation in wikipedia implements the respective formulae that specializes in the below aspects
Users can now create Percentile by explicitly passing this enum;
such as by invoking Percentile#withEstimationType(EstimationType)
References:
| Modifier and Type | Field and Description |
|---|---|
| public static final Percentile. | LEGACY
This is the default type used in the |
| private final String | name
Hides java. |
| public static final Percentile. | R_1
The method R_1 has the following formulae for index and estimates \( \begin{align} &index= Np + 1/2\, \\ &estimate= x_{\lceil h\,-\,1/2 \rceil} \\ &minLimit = 0 \\ \end{align}\) |
| public static final Percentile. | R_2
The method R_2 has the following formulae for index and estimates \( \begin{align} &index= Np + 1/2\, \\ &estimate=\frac{x_{\lceil h\,-\,1/2 \rceil} + x_{\lfloor h\,+\,1/2 \rfloor}}{2} \\ &minLimit = 0 \\ &maxLimit = 1 \\ \end{align}\) |
| public static final Percentile. | R_3
The method R_3 has the following formulae for index and estimates \( \begin{align} &index= Np \\ &estimate= x_{\lfloor h \rceil}\, \\ &minLimit = 0.5/N \\ \end{align}\) |
| public static final Percentile. | R_4
The method R_4 has the following formulae for index and estimates \( \begin{align} &index= Np\, \\ &estimate= x_{\lfloor h \rfloor} + (h - \lfloor h \rfloor) (x_{\lfloor h \rfloor + 1} - x_{\lfloor h \rfloor}) \\ &minLimit = 1/N \\ &maxLimit = 1 \\ \end{align}\) |
| public static final Percentile. | R_5
The method R_5 has the following formulae for index and estimates \( \begin{align} &index= Np + 1/2\\ &estimate= x_{\lfloor h \rfloor} + (h - \lfloor h \rfloor) (x_{\lfloor h \rfloor + 1} - x_{\lfloor h \rfloor}) \\ &minLimit = 0.5/N \\ &maxLimit = (N-0.5)/N \end{align}\) |
| public static final Percentile. | R_6
The method R_6 has the following formulae for index and estimates \( \begin{align} &index= (N + 1)p \\ &estimate= x_{\lfloor h \rfloor} + (h - \lfloor h \rfloor) (x_{\lfloor h \rfloor + 1} - x_{\lfloor h \rfloor}) \\ &minLimit = 1/(N+1) \\ &maxLimit = N/(N+1) \\ \end{align}\) Note This method computes the index in a manner very close to the default Commons Math Percentile existing implementation. |
| public static final Percentile. | R_7
The method R_7 implements Microsoft Excel style computation has the following formulae for index and estimates. |
| public static final Percentile. | R_8
The method R_8 has the following formulae for index and estimates \( \begin{align} &index = (N + 1/3)p + 1/3 \\ &estimate = x_{\lfloor h \rfloor} + (h - \lfloor h \rfloor) (x_{\lfloor h \rfloor + 1} - x_{\lfloor h \rfloor}) \\ &minLimit = (2/3)/(N+1/3) \\ &maxLimit = (N-1/3)/(N+1/3) \\ \end{align}\) As per Ref [2,3] this approach is most recommended as it provides an approximate median-unbiased estimate regardless of distribution. |
| public static final Percentile. | R_9
The method R_9 has the following formulae for index and estimates \( \begin{align} &index = (N + 1/4)p + 3/8\\ &estimate = x_{\lfloor h \rfloor} + (h - \lfloor h \rfloor) (x_{\lfloor h \rfloor + 1} - x_{\lfloor h \rfloor}) \\ &minLimit = (5/8)/(N+1/4) \\ &maxLimit = (N-3/8)/(N+1/4) \\ \end{align}\) |
| Access | Constructor and Description |
|---|---|
| private |
| Modifier and Type | Method and Description |
|---|---|
| protected double | Returns: estimated percentilearray of numbers to be used for finding the percentile work, final int[] an earlier populated cache if exists; will be used pivotsHeap, final double indicated positional index prior computed from calling
pos, final int index(double, int)size of array considered length, final KthSelector a selector)KthSelector used for pivoting during searchEstimation based on Kth selection. |
| protected double | Returns: estimated percentilearray of numbers to be used for finding the percentile work, final int[] a prior cached heap which can speed up estimation pivotsHeap, final double the pth quantile to be computed p, final KthSelector a selector)KthSelector used for pivoting during searchEvaluate method to compute the percentile for a given bounded array using earlier computed pivots heap. |
| public double | Returns: estimated percentilearray of numbers to be used for finding the percentile work, final double the pth quantile to be computed p, final KthSelector a selector)KthSelector used for pivoting during searchEvaluate method to compute the percentile for a given bounded array. |
| pack-priv String | |
| protected abstract double | |
| public static Percentile. | |
| public static Percentile. |
| LEGACY | back to summary |
|---|---|
| public static final Percentile. This is the default type used in the | |
| name | back to summary |
|---|---|
| private final String name Hides java. Simple name such as R-1, R-2 corresponding to those in wikipedia. | |
| R_1 | back to summary |
|---|---|
| public static final Percentile. The method R_1 has the following formulae for index and estimates | |
| R_2 | back to summary |
|---|---|
| public static final Percentile. The method R_2 has the following formulae for index and estimates | |
| R_3 | back to summary |
|---|---|
| public static final Percentile. The method R_3 has the following formulae for index and estimates | |
| R_4 | back to summary |
|---|---|
| public static final Percentile. The method R_4 has the following formulae for index and estimates | |
| R_5 | back to summary |
|---|---|
| public static final Percentile. The method R_5 has the following formulae for index and estimates | |
| R_6 | back to summary |
|---|---|
| public static final Percentile. The method R_6 has the following formulae for index and estimates Note This method computes the index in a manner very close to the default Commons Math Percentile existing implementation. However the difference to be noted is in picking up the limits with which first element (p<1(N+1)) and last elements (p>N/(N+1))are done. While in default case; these are done with p=0 and p=1 respectively. | |
| R_7 | back to summary |
|---|---|
| public static final Percentile. The method R_7 implements Microsoft Excel style computation has the
following formulae for index and estimates. | |
| R_8 | back to summary |
|---|---|
| public static final Percentile. The method R_8 has the following formulae for index and estimates As per Ref [2,3] this approach is most recommended as it provides an approximate median-unbiased estimate regardless of distribution. | |
| R_9 | back to summary |
|---|---|
| public static final Percentile. The method R_9 has the following formulae for index and estimates | |
| EstimationType | back to summary |
|---|---|
| private EstimationType(final String type) Constructor
| |
| estimate | back to summary |
|---|---|
| protected double estimate(final double[] work, final int[] pivotsHeap, final double pos, final int length, final KthSelector selector) Estimation based on Kth selection. This may be overridden in specific enums to compute slightly different estimations.
| |
| evaluate | back to summary |
|---|---|
| protected double evaluate(final double[] work, final int[] pivotsHeap, final double p, final KthSelector selector) Evaluate method to compute the percentile for a given bounded array
using earlier computed pivots heap.
| |
| evaluate | back to summary |
|---|---|
| public double evaluate(final double[] work, final double p, final KthSelector selector) Evaluate method to compute the percentile for a given bounded array.
This basically calls the
| |
| getName | back to summary |
|---|---|
| pack-priv String getName() Gets the name of the enum
| |
| index | back to summary |
|---|---|
| protected abstract double index(final double p, final int length) Finds the index of array that can be used as starting index to
| |
| valueOf | back to summary |
|---|---|
| public static Percentile. | |
| values | back to summary |
|---|---|
| public static Percentile. | |