Digamos que tengo lo siguiente:

>>> numpy.random.seed(42)
>>> df = pandas.DataFrame(numpy.random.randint(0, 100, 19), columns=['val'], index=pandas.date_range('2021-03-01', '2021-03-04', freq='4H'))
>>> df
                     val
2021-03-01 00:00:00   51
2021-03-01 04:00:00   92
2021-03-01 08:00:00   14
2021-03-01 12:00:00   71
2021-03-01 16:00:00   60
2021-03-01 20:00:00   20
2021-03-02 00:00:00   82
2021-03-02 04:00:00   86
2021-03-02 08:00:00   74
2021-03-02 12:00:00   74
2021-03-02 16:00:00   87
2021-03-02 20:00:00   99
2021-03-03 00:00:00   23
2021-03-03 04:00:00    2
2021-03-03 08:00:00   21
2021-03-03 12:00:00   52
2021-03-03 16:00:00    1
2021-03-03 20:00:00   87
2021-03-04 00:00:00   29
>>> df.groupby(pandas.Grouper(freq='1D')).quantile(0.95, interpolation='higher')
            val
2021-03-01   92
2021-03-02   99
2021-03-03   87
2021-03-04   29

¿Cómo puedo obtener también los índices donde se encuentran los cuantiles dentro de cada grupo? Es decir. mi salida deseada es:

            val  idx
2021-03-01   92  2021-03-01 04:00:00
2021-03-02   99  2021-03-02 20:00:00
2021-03-03   87  2021-03-03 20:00:00
2021-03-04   29  2021-03-04 00:00:00
2
levant pied 4 mar. 2021 a las 06:32

2 respuestas

La mejor respuesta

En lugar de cuantil, calcule rank dentro de cada grupo y averigüe qué valores son >= su cuantil (ya que usa interpolate='higher'). Luego ordene el DataFrame, mantenga solo las filas por encima de su cuantil y tome el first dentro del grupo. Asignar una columna como índice trae esto.

m = df.resample('D')['val'].rank(method='dense', pct=True).ge(0.95)
df1 = df.assign(index=df.index)[m].sort_values('val')

df1.groupby(df1.index.normalize()).first()

            val               index
2021-03-01   92 2021-03-01 04:00:00
2021-03-02   99 2021-03-02 20:00:00
2021-03-03   87 2021-03-03 20:00:00
2021-03-04   29 2021-03-04 00:00:00
2
ALollz 4 mar. 2021 a las 15:52

Una opción es usar groupby().transform:

q95 = (df.groupby(pd.Grouper(freq='1D'))['val']
   .transform('quantile', q=0.95, interpolation='higher')
)
df[df['val']== q95]

Salida:

                     val
2021-03-01 04:00:00   92
2021-03-02 20:00:00   99
2021-03-03 20:00:00   87
2021-03-04 00:00:00   29
1
Quang Hoang 4 mar. 2021 a las 04:19