python - tutorial - Los pandas obtienen los mejores n registros dentro de cada grupo
promedio pandas python (2)
¿Has df.groupby(''id'').head(2)
Ouput generado:
>>> df.groupby(''id'').head(2)
id value
id
1 0 1 1
1 1 2
2 3 2 1
4 2 2
3 7 3 1
4 8 4 1
(Tenga en cuenta que es posible que deba ordenar / ordenar antes, según sus datos)
EDITAR: Como mencionó el interrogador, use df.groupby(''id'').head(2).reset_index(drop=True)
para eliminar el multindex y aplanar los resultados.
>>> df.groupby(''id'').head(2).reset_index(drop=True)
id value
0 1 1
1 1 2
2 2 1
3 2 2
4 3 1
5 4 1
Supongamos que tengo panda DataFrame así:
>>> df = pd.DataFrame({''id'':[1,1,1,2,2,2,2,3,4],''value'':[1,2,3,1,2,3,4,1,1]})
>>> df
id value
0 1 1
1 1 2
2 1 3
3 2 1
4 2 2
5 2 3
6 2 4
7 3 1
8 4 1
Quiero obtener un nuevo DataFrame con los 2 registros principales para cada ID, como este:
id value
0 1 1
1 1 2
3 2 1
4 2 2
7 3 1
8 4 1
Puedo hacerlo con registros de numeración dentro del grupo después del grupo de la siguiente manera:
>>> dfN = df.groupby(''id'').apply(lambda x:x[''value''].reset_index()).reset_index()
>>> dfN
id level_1 index value
0 1 0 0 1
1 1 1 1 2
2 1 2 2 3
3 2 0 3 1
4 2 1 4 2
5 2 2 5 3
6 2 3 6 4
7 3 0 7 1
8 4 0 8 1
>>> dfN[dfN[''level_1''] <= 1][[''id'', ''value'']]
id value
0 1 1
1 1 2
3 2 1
4 2 2
7 3 1
8 4 1
¿Pero hay un enfoque más eficaz / elegante para hacer esto? Y también hay un enfoque más elegante para los registros de números dentro de cada grupo (como la función de ventana SQL row_number() ).
Desde 0.14.1 , ahora puede hacer nlargest
y nsmallest
en un objeto groupby
:
In [23]: df.groupby(''id'')[''value''].nlargest(2)
Out[23]:
id
1 2 3
1 2
2 6 4
5 3
3 7 1
4 8 1
dtype: int64
Hay una ligera rareza en la que también obtienes el índice original, pero esto podría ser realmente útil según tu índice original.
Si no le interesa, puede hacer .reset_index(level=1, drop=True)
para deshacerse de él por completo.
(Nota: desde 0.17.1 también podrá hacer esto en un DataFrameGroupBy, pero por ahora solo funciona con Series
y SeriesGroupBy
).