I think your example input/output does not correspond to typical ways of calculating percentile. If you calculate the percentile as "proportion of data points strictly less than this value", then the top value should be 0.8 (since 4 of 5 values are less than the largest one). If you calculate it as "percent of data points less than or equal to this value", then the bottom value should be 0.2 (since 1 of 5 values equals the smallest one). Thus the percentiles would be [0, 0.2, 0.4, 0.6, 0.8] or [0.2, 0.4, 0.6, 0.8, 1]. Your definition seems to be "the number of data points strictly less than this value, considered as a proportion of the number of data points not equal to this value", but in my experience this is not a common definition (see for instance wikipedia).

With the typical percentile definitions, the percentile of a data point is equal to its rank divided by the number of data points. (See for instance this question on Stats SE asking how to do the same thing in R.) Differences in how to compute the percentile amount to differences in how to compute the rank (for instance, how to rank tied values). The scipy.stats.percentileofscore function provides four ways of computing percentiles:

>>> x = [1, 1, 2, 2, 17]
>>> [stats.percentileofscore(x, a, 'rank') for a in x]
[30.0, 30.0, 70.0, 70.0, 100.0]
>>> [stats.percentileofscore(x, a, 'weak') for a in x]
[40.0, 40.0, 80.0, 80.0, 100.0]
>>> [stats.percentileofscore(x, a, 'strict') for a in x]
[0.0, 0.0, 40.0, 40.0, 80.0]
>>> [stats.percentileofscore(x, a, 'mean') for a in x]
[20.0, 20.0, 60.0, 60.0, 90.0]

(I used a dataset containing ties to illustrate what happens in such cases.)

The "rank" method assigns tied groups a rank equal to the average of the ranks they would cover (i.e., a three-way tie for 2nd place gets a rank of 3 because it "takes up" ranks 2, 3 and 4). The "weak" method assigns a percentile based on the proportion of data points less than or equal to a given point; "strict" is the same but counts proportion of points strictly less than the given point. The "mean" method is the average of the latter two.

As Kevin H. Lin noted, calling percentileofscore in a loop is inefficient since it has to recompute the ranks on every pass. However, these percentile calculations can be easily replicated using different ranking methods provided by scipy.stats.rankdata, letting you calculate all the percentiles at once:

>>> from scipy import stats
>>> stats.rankdata(x, "average")/len(x)
array([ 0.3,  0.3,  0.7,  0.7,  1. ])
>>> stats.rankdata(x, 'max')/len(x)
array([ 0.4,  0.4,  0.8,  0.8,  1. ])
>>> (stats.rankdata(x, 'min')-1)/len(x)
array([ 0. ,  0. ,  0.4,  0.4,  0.8])

In the last case the ranks are adjusted down by one to make them start from 0 instead of 1. (I've omitted "mean", but it could easily be obtained by averaging the results of the latter two methods.)

I did some timings. With small data such as that in your example, using rankdata is somewhat slower than Kevin H. Lin's solution (presumably due to the overhead scipy incurs in converting things to numpy arrays under the hood) but faster than calling percentileofscore in a loop as in reptilicus's answer:

In [11]: %timeit [stats.percentileofscore(x, i) for i in x]
1000 loops, best of 3: 414 µs per loop

In [12]: %timeit list_to_percentiles(x)
100000 loops, best of 3: 11.1 µs per loop

In [13]: %timeit stats.rankdata(x, "average")/len(x)
10000 loops, best of 3: 39.3 µs per loop

With a large dataset, however, the performance advantage of numpy takes effect and using rankdata is 10 times faster than Kevin's list_to_percentiles:

In [18]: x = np.random.randint(0, 10000, 1000)

In [19]: %timeit [stats.percentileofscore(x, i) for i in x]
1 loops, best of 3: 437 ms per loop

In [20]: %timeit list_to_percentiles(x)
100 loops, best of 3: 1.08 ms per loop

In [21]: %timeit stats.rankdata(x, "average")/len(x)
10000 loops, best of 3: 102 µs per loop

This advantage will only become more pronounced on larger and larger datasets.

Answer from BrenBarn on Stack Overflow
Top answer
1 of 10
61

I think your example input/output does not correspond to typical ways of calculating percentile. If you calculate the percentile as "proportion of data points strictly less than this value", then the top value should be 0.8 (since 4 of 5 values are less than the largest one). If you calculate it as "percent of data points less than or equal to this value", then the bottom value should be 0.2 (since 1 of 5 values equals the smallest one). Thus the percentiles would be [0, 0.2, 0.4, 0.6, 0.8] or [0.2, 0.4, 0.6, 0.8, 1]. Your definition seems to be "the number of data points strictly less than this value, considered as a proportion of the number of data points not equal to this value", but in my experience this is not a common definition (see for instance wikipedia).

With the typical percentile definitions, the percentile of a data point is equal to its rank divided by the number of data points. (See for instance this question on Stats SE asking how to do the same thing in R.) Differences in how to compute the percentile amount to differences in how to compute the rank (for instance, how to rank tied values). The scipy.stats.percentileofscore function provides four ways of computing percentiles:

>>> x = [1, 1, 2, 2, 17]
>>> [stats.percentileofscore(x, a, 'rank') for a in x]
[30.0, 30.0, 70.0, 70.0, 100.0]
>>> [stats.percentileofscore(x, a, 'weak') for a in x]
[40.0, 40.0, 80.0, 80.0, 100.0]
>>> [stats.percentileofscore(x, a, 'strict') for a in x]
[0.0, 0.0, 40.0, 40.0, 80.0]
>>> [stats.percentileofscore(x, a, 'mean') for a in x]
[20.0, 20.0, 60.0, 60.0, 90.0]

(I used a dataset containing ties to illustrate what happens in such cases.)

The "rank" method assigns tied groups a rank equal to the average of the ranks they would cover (i.e., a three-way tie for 2nd place gets a rank of 3 because it "takes up" ranks 2, 3 and 4). The "weak" method assigns a percentile based on the proportion of data points less than or equal to a given point; "strict" is the same but counts proportion of points strictly less than the given point. The "mean" method is the average of the latter two.

As Kevin H. Lin noted, calling percentileofscore in a loop is inefficient since it has to recompute the ranks on every pass. However, these percentile calculations can be easily replicated using different ranking methods provided by scipy.stats.rankdata, letting you calculate all the percentiles at once:

>>> from scipy import stats
>>> stats.rankdata(x, "average")/len(x)
array([ 0.3,  0.3,  0.7,  0.7,  1. ])
>>> stats.rankdata(x, 'max')/len(x)
array([ 0.4,  0.4,  0.8,  0.8,  1. ])
>>> (stats.rankdata(x, 'min')-1)/len(x)
array([ 0. ,  0. ,  0.4,  0.4,  0.8])

In the last case the ranks are adjusted down by one to make them start from 0 instead of 1. (I've omitted "mean", but it could easily be obtained by averaging the results of the latter two methods.)

I did some timings. With small data such as that in your example, using rankdata is somewhat slower than Kevin H. Lin's solution (presumably due to the overhead scipy incurs in converting things to numpy arrays under the hood) but faster than calling percentileofscore in a loop as in reptilicus's answer:

In [11]: %timeit [stats.percentileofscore(x, i) for i in x]
1000 loops, best of 3: 414 µs per loop

In [12]: %timeit list_to_percentiles(x)
100000 loops, best of 3: 11.1 µs per loop

In [13]: %timeit stats.rankdata(x, "average")/len(x)
10000 loops, best of 3: 39.3 µs per loop

With a large dataset, however, the performance advantage of numpy takes effect and using rankdata is 10 times faster than Kevin's list_to_percentiles:

In [18]: x = np.random.randint(0, 10000, 1000)

In [19]: %timeit [stats.percentileofscore(x, i) for i in x]
1 loops, best of 3: 437 ms per loop

In [20]: %timeit list_to_percentiles(x)
100 loops, best of 3: 1.08 ms per loop

In [21]: %timeit stats.rankdata(x, "average")/len(x)
10000 loops, best of 3: 102 µs per loop

This advantage will only become more pronounced on larger and larger datasets.

2 of 10
23

I think you want scipy.stats.percentileofscore

Example:

percentileofscore([1, 2, 3, 4], 3)
75.0
percentiles = [percentileofscore(data, i) for i in data]
Discussions

Python formula to find Percentile
You can use math.ceil() https://www.delftstack.com/howto/python/python-percentile/#calculate-percentile-in-python-using-the-math-package More on reddit.com
🌐 r/learnpython
2
1
April 2, 2021
python - Find the percentile of a value - Stack Overflow
One definition of percentile, often ... the P-th percentile ( 0 < P ≤ 100 ) of a list of N ordered values (sorted from least to greatest) is the smallest value in the list such that no more than P percent of the data is strictly less than the value and at least P percent of the data is less than or equal to that value. ... I also assume that you don't have a uniform distribution and number can repeat. You can get a dictionary ... More on stackoverflow.com
🌐 stackoverflow.com
February 6, 2021
python - How to calculate percentile - Stack Overflow
When you have a list of numbers [1, 3,5, 7, 7, 9, 11, 11, 11, 24] I want a list of percentiles [10%,20%,30%, 40%, 40%, 60%, 70%, 70% 70%, 100%] In plain python code, percentiles = [] prev_value ... More on stackoverflow.com
🌐 stackoverflow.com
python - Finding the percentile corresponding to a threshold - Code Review Stack Exchange
I need to find which percentile of a group of numbers is over a threshold value. Is there a way that this can be speed up? My implementation is much too slow for the intended application. In case this changes anything, I am running my program using mpirun -np 100 python program.py. More on codereview.stackexchange.com
🌐 codereview.stackexchange.com
March 18, 2016
🌐
W3Schools
w3schools.com › python › python_ml_percentile.asp
Python Machine Learning Percentiles
Remove List Duplicates Reverse a String Add Two Numbers · Python Examples Python Compiler Python Exercises Python Quiz Python Challenges Python Practice Problems Python Server Python Syllabus Python Study Plan Python Interview Q&A Python Training ... Percentiles are used in statistics to give you a number that describes the value that a given percent of the values are lower than.
🌐
Statology
statology.org › home › how to calculate percentiles in python (with examples)
How to Calculate Percentiles in Python (With Examples)
November 3, 2020 - For example, the 90th percentile of a dataset is the value that cuts of the bottom 90% of the data values from the top 10% of data values. We can quickly calculate percentiles in Python by using the numpy.percentile() function, which uses the ...
🌐
Delft Stack
delftstack.com › home › howto › python › python percentile
How to Calculate Percentile in Python | Delft Stack
February 2, 2024 - In Python, the percentile of a one-dimensional integer array can be calculated using scipy and NumPy libraries, user-defined function, math package, statistics package, and interpolation method.
🌐
GeeksforGeeks
geeksforgeeks.org › python › numpy-percentile-in-python
numpy.percentile() in python - GeeksforGeeks
June 21, 2025 - A percentile is a measure indicating the value below which a given percentage of observations in a group falls. Example: Python · import numpy as np a = np.array([1, 3, 5, 7, 9]) res = np.percentile(a, 50) print(res) Output · 5.0 · numpy.percentile(a, q, axis=None, out=None, overwrite_input=False, interpolation='linear', keepdims=False, method='linear') Parameters: Returns: The q-th percentile(s) of the array elements. If q is a list, it returns multiple percentiles.
🌐
YouTube
youtube.com › codesolve
python get percentile of value in list - YouTube
Download this code from https://codegive.com Title: Python Tutorial: Getting the Percentile of a Value in a ListIntroduction:Percentiles are a statistical me...
Published: December 11, 2023
Views: 4
Find elsewhere
🌐
ActiveState
code.activestate.com › recipes › 511478-finding-the-percentile-of-the-values
Finding the percentile of the values « Python recipes « ActiveState Code
April 17, 2007 - This function find the percentile of a list of values. Note that the list must be sorted already. ... >>> percentile(range(10),0.25) 2.25 >>> percentile(range(10),0.75) 6.75 >>> median(range(10)) 4.5 >>> median(range(11)) 5 ... Correction. That does the interpolation in the wrong direction ...
🌐
Data Science Parichay
datascienceparichay.com › home › blog › calculate percentile in python
Calculate Percentile in Python - Data Science Parichay
October 9, 2021 - You can use the numpy percentile() function on array or sequence of values to get the nth percentile value in Python.
🌐
GitHub
github.com › bycoffe › python-math › blob › master › calculate › percentile.py
python-math/calculate/percentile.py at master · bycoffe/python-math
return (len([i for i in data_list if i < score]) + len([i for i in data_list if i <= score])) * 50 / float(n) ... raise ValueError("The kind kwarg must be 'strict', 'weak' or 'mean'.
Author: bycoffe
🌐
Finxter
blog.finxter.com › home › learn python blog › how to calculate percentiles in python
How to Calculate Percentiles in Python - Be on the Right Side of Change
February 8, 2021 - Let’s now try to calculate the values of the 5th, 25th, 50th, 75th and 95th percentiles. We can hence build a list, called “perc_func” that contains all those percentiles, evaluated through our function. Before doing that, we define a list called “index” that contains the values of the percentiles that we are interested in.
🌐
NumPy
numpy.org › doc › stable › reference › generated › numpy.percentile.html
numpy.percentile — NumPy v2.5 Manual
An array of weights associated with the values in a. Each value in a contributes to the percentile according to its associated weight. The weights array can either be 1-D (in which case its length must be the size of a along the given axis) or of the same shape as a.
🌐
Plain English
python.plainenglish.io › use-python-to-calculate-the-percentile-in-a-list-of-numbers-ad16a2b6c71c
Use Python to Calculate the Percentile in a List of Numbers | Python in Plain English
May 26, 2022 - I have written this function in the Python programming language, and since the numbering system in Python begins with zero, I have had to subtract one from the value n to make it compliant with the programming language. Join Medium for free to get updates from this writer. ... Define the function, find_percentile, which takes a list of numbers as input.
🌐
Scicoding
scicoding.com › calculating-percentiles-in-python
How to Calculate Percentiles in Python: 4 Different Methods
February 20, 2023 - We go through 4 different ways of calculating percentile in Python. See how it's done using NumPy, SciPy & Pandas + Python-only implementation.
🌐
Codecademy
codecademy.com › docs › python:numpy › built-in functions › .percentile()
Python:NumPy | Built-in Functions | .percentile() | Codecademy
July 25, 2025 - Returns the q-th percentile(s) of the array elements. If q is a single percentile, returns a scalar. If multiple percentiles are given, returns an array. This example demonstrates how to calculate a single percentile from a one-dimensional array: ... Quartiles: [ 5.5 10. 14.5] ... The 50th percentile represents the median value, which is the middle value when the data is sorted.