Respuesta rápida:
La forma más sencilla de obtener recuentos de filas por grupo es llamando .size()
, lo que devuelve un Series
:
df.groupby(['col1','col2']).size()
Por lo general, desea este resultado como un DataFrame
(en lugar de a Series
) para que pueda hacer:
df.groupby(['col1', 'col2']).size().reset_index(name='counts')
Si desea averiguar cómo calcular los recuentos de filas y otras estadísticas para cada grupo, continúe leyendo a continuación.
Ejemplo detallado:
Considere el siguiente marco de datos de ejemplo:
In [2]: df
Out[2]:
col1 col2 col3 col4 col5 col6
0 A B 0.20 -0.61 -0.49 1.49
1 A B -1.53 -1.01 -0.39 1.82
2 A B -0.44 0.27 0.72 0.11
3 A B 0.28 -1.32 0.38 0.18
4 C D 0.12 0.59 0.81 0.66
5 C D -0.13 -1.65 -1.64 0.50
6 C D -1.42 -0.11 -0.18 -0.44
7 E F -0.00 1.42 -0.26 1.17
8 E F 0.91 -0.47 1.35 -0.34
9 G H 1.48 -0.63 -1.14 0.17
Primero usemos .size()
para obtener los recuentos de filas:
In [3]: df.groupby(['col1', 'col2']).size()
Out[3]:
col1 col2
A B 4
C D 3
E F 2
G H 1
dtype: int64
Luego, usemos .size().reset_index(name='counts')
para obtener los recuentos de filas:
In [4]: df.groupby(['col1', 'col2']).size().reset_index(name='counts')
Out[4]:
col1 col2 counts
0 A B 4
1 C D 3
2 E F 2
3 G H 1
Incluyendo resultados para más estadísticas
Cuando desea calcular estadísticas sobre datos agrupados, generalmente se ve así:
In [5]: (df
...: .groupby(['col1', 'col2'])
...: .agg({
...: 'col3': ['mean', 'count'],
...: 'col4': ['median', 'min', 'count']
...: }))
Out[5]:
col4 col3
median min count mean count
col1 col2
A B -0.810 -1.32 4 -0.372500 4
C D -0.110 -1.65 3 -0.476667 3
E F 0.475 -0.47 2 0.455000 2
G H -0.630 -0.63 1 1.480000 1
El resultado anterior es un poco molesto de tratar debido a las etiquetas de columna anidadas y también porque los recuentos de filas son por columna.
Para obtener más control sobre la salida, generalmente divido las estadísticas en agregaciones individuales que luego combino usando join
. Se parece a esto:
In [6]: gb = df.groupby(['col1', 'col2'])
...: counts = gb.size().to_frame(name='counts')
...: (counts
...: .join(gb.agg({'col3': 'mean'}).rename(columns={'col3': 'col3_mean'}))
...: .join(gb.agg({'col4': 'median'}).rename(columns={'col4': 'col4_median'}))
...: .join(gb.agg({'col4': 'min'}).rename(columns={'col4': 'col4_min'}))
...: .reset_index()
...: )
...:
Out[6]:
col1 col2 counts col3_mean col4_median col4_min
0 A B 4 -0.372500 -0.810 -1.32
1 C D 3 -0.476667 -0.110 -1.65
2 E F 2 0.455000 0.475 -0.47
3 G H 1 1.480000 -0.630 -0.63
Notas al pie
El código utilizado para generar los datos de prueba se muestra a continuación:
In [1]: import numpy as np
...: import pandas as pd
...:
...: keys = np.array([
...: ['A', 'B'],
...: ['A', 'B'],
...: ['A', 'B'],
...: ['A', 'B'],
...: ['C', 'D'],
...: ['C', 'D'],
...: ['C', 'D'],
...: ['E', 'F'],
...: ['E', 'F'],
...: ['G', 'H']
...: ])
...:
...: df = pd.DataFrame(
...: np.hstack([keys,np.random.randn(10,4).round(2)]),
...: columns = ['col1', 'col2', 'col3', 'col4', 'col5', 'col6']
...: )
...:
...: df[['col3', 'col4', 'col5', 'col6']] = \
...: df[['col3', 'col4', 'col5', 'col6']].astype(float)
...:
Descargo de responsabilidad:
Si algunas de las columnas que está agregando tienen valores nulos, entonces realmente desea ver la fila del grupo que cuenta como una agregación independiente para cada columna. De lo contrario, es posible que se equivoque sobre cuántos registros se están utilizando realmente para calcular cosas como la media porque los pandas dejarán caer NaN
entradas en el cálculo de la media sin informarle al respecto.
df[['col1','col2','col3','col4']].groupby(['col1','col2']).agg(['mean', 'count'])