Les fonctions quantiles nous donnent le quantile d'un pandas series s,
Par exemple.
s.quantile (0,9) est 4,2
Existe-t-il la fonction inverse (c'est-à-dire la distribution cumulative) qui trouve la valeur x telle que
s.quantile (x) = 4
Merci
J'avais la même question que toi! J'ai trouvé un moyen facile d'obtenir l'inverse du quantile en utilisant 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)
Le tri peut être coûteux, si vous recherchez une valeur unique, je suppose que vous feriez mieux de la calculer avec:
s = pd.Series(np.random.uniform(size=1000))
( s < 0.7 ).astype(int).mean() # =0.7ish
Il y a probablement un moyen d'éviter le shenanigan int (bool).
Il n'y a pas de doublure à ma connaissance, mais vous pouvez y arriver avec 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
Nous pouvons maintenant voir que les deux fonctions sont inverses l'une de l'autre.
>>> df['a'].quantile(0.57)
0.61167933268395969
>>> interp(0.61167933268395969)
array(0.57)
>>> interp(df['a'].quantile(0.43))
array(0.43)
interp peut également prendre en liste, un tableau numpy ou une série de données pandas, n'importe quel itérateur vraiment!
Je viens de rencontrer le même problème. Voici mes deux cents.
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
Mathématiquement parlant, vous essayez de trouver CDF ou de renvoyer la probabilité que s
soit inférieur ou égal à une valeur ou un quantile de q
:
F(q) = Pr[s <= q]
On peut utiliser numpy et essayer ce code à une ligne:
np.mean(s.to_numpy() <= q)