что такое обратная функция квантиля на серии панд?
квантильные функции дают нам квантиль данного ряда панд s,
Э. Г.
s.квантиль (0.9) равен 4.2
есть ли обратная функция (т. е. кумулятивное распределение), которая находит значение x таким, что
s.квантиль (x)=4
спасибо
4 ответов
У меня был тот же вопрос, Что ты сделал! Я нашел простой способ получить обратный квантиль с помощью scipy.
#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)
сортировка может быть дорогостоящей, если вы ищете одно значение, я думаю, вам лучше вычислить его с помощью:
s = pd.Series(np.random.uniform(size=1000))
( s < 0.7 ).astype(int).mean() # =0.7ish
вероятно, есть способ избежать махинаций int(bool).
нет 1-лайнера, о котором я знаю, но вы можете достичь этого с помощью scipy:
import pandas as pd
import numpy as np
from scipy.interpolate import interp1d
# set up a sample dataframe
df = pd.DataFrame(np.random.uniform(0,1,(11)), columns=['a'])
# sort it by the desired series and caculate the percentile
sdf = df.sort('a').reset_index()
sdf['b'] = sdf.index / float(len(sdf) - 1)
# setup the interpolator using the value as the index
interp = interp1d(sdf['a'], sdf['b'])
# a is the value, b is the percentile
>>> sdf
index a b
0 10 0.030469 0.0
1 3 0.144445 0.1
2 4 0.304763 0.2
3 1 0.359589 0.3
4 7 0.385524 0.4
5 5 0.538959 0.5
6 8 0.642845 0.6
7 6 0.667710 0.7
8 9 0.733504 0.8
9 2 0.905646 0.9
10 0 0.961936 1.0
теперь мы можем видеть, что две функции являются инверсиями друг друга.
>>> df['a'].quantile(0.57)
0.61167933268395969
>>> interp(0.61167933268395969)
array(0.57)
>>> interp(df['a'].quantile(0.43))
array(0.43)
interp также может принимать список, массив numpy или серию данных pandas, любой итератор!
просто столкнулся с той же проблемой. Вот мои два цента.
def inverse_percentile(arr, num):
arr = sorted(arr)
i_arr = [i for i, x in enumerate(arr) if x > num]
return i_arr[0] / len(arr) if len(i_arr) > 0 else 1