¿cuál es el inverso de la función cuantil en una serie de pandas?

Las funciones de cuantiles nos dan el cuantil de una serie de pandas dadas,

P.ej

s.quantile (0.9) es 4.2

¿Existe la función inversa (es decir, la distribución acumulada) que encuentra el valor x tal que

s.quantile (x) = 4

Gracias

¡Tenía la misma pregunta que tú! Encontré una manera fácil de obtener el inverso de cuantil utilizando 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) 

La clasificación puede ser costosa, si busca un valor único, creo que sería mejor que lo calculara con:

 s = pd.Series(np.random.uniform(size=1000)) ( s < 0.7 ).astype(int).mean() # =0.7ish 

Probablemente hay una manera de evitar el shenanigan int (bool).

No conozco ningún 1-liner, pero puedes lograrlo con 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 ab 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 

Ahora podemos ver que las dos funciones son inversas entre sí.

 >>> df['a'].quantile(0.57) 0.61167933268395969 >>> interp(0.61167933268395969) array(0.57) >>> interp(df['a'].quantile(0.43)) array(0.43) 

Interp también puede incluir en la lista, una matriz numpy o una serie de datos de pandas, ¡cualquier iterador realmente!

Acabo de encontrar el mismo problema. Aquí están mis dos centavos.

 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