First of all, according to the docs, the default method used for interpolation is linear:
linear: i + (j - i) * fraction, where fraction is the fractional part of the index surrounded by i and j.
We first need to find out how index is calculated (and then get its fractional part):
index = distance_between_first_and_last_element * q
So, in your example, we'd have a distance of 7 (because 2 and 19 are 7 positions apart). This leads to:
index = 7 * 0.3 = 2.1
Of course, we need to keep only the fractional part of it, which is simply 0.1, so fraction is equal to 0.1.
Moreover, the 0.3 quantile that you've asked for is between 5 and 8 (which are numbers in your list), so these will stand for i and j respectively.
Why? Because your index is 2.1, which is between 2 and 3, so:
i = s[2] # which is equal to 5 in your Series
j = s[3] # which is equal to 8 in your Series
All these lead to:
5 + (8-5) * 0.1
which equals to:
5.3
According to the same logic, we can calculate the 0.25 percentile:
index = 7 * 0.25 # 1.75
fraction = 0.75 # the fractional part of index
i = s[1] # 4
j = s[2] # 5
answer = 4 + (5-4) * 0.75 -> 4.75
Answer from theodosis on Stack OverflowVideos
Use scipy.stats.percentileofscore:
# libs required
from scipy import stats
import pandas as pd
import numpy as np
# generate ramdom data with same seed (to be reproducible)
np.random.seed(seed=1)
df = pd.DataFrame(np.random.uniform(0, 1, (10)), columns=['a'])
# quantile function
x = df.quantile(0.5)[0]
# inverse of quantile
stats.percentileofscore(df['a'], x)
Sorting can be expensive, if you look for a single value I'd guess you'd be better of computing it with:
s = pd.Series(np.random.uniform(size=1000))
( s < 0.7 ).astype(int).mean() # =0.7ish
There's probably a way to avoid the int(bool) shenanigan.