web-dev-qa-db-fra.com

quel est l'inverse de la fonction quantile sur une série pandas?

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

36
Mannaggia

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)
52
fernandosjp

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).

15
ILoveCoding

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!

7
Mike

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
4
Calvin Ku

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)