Cómo contar el número de filas por grupo (y otras estadísticas) en pandas grupo?
Tengo un marco de datos df
y uso varias columnas desde él hasta groupby
:
df['col1','col2','col3','col4'].groupby(['col1','col2']).mean()
De la manera anterior casi obtengo la tabla (data frame) que necesito. Lo que falta es una columna adicional que contiene el número de filas en cada grupo. En otras palabras, tengo medios, pero también me gustaría saber cuántos números se utilizaron para obtener estos medios. Por ejemplo, en el primer grupo hay 8 valores y en el segundo 10, y así sucesivamente.
3 answers
En el objeto groupby
, la función agg
puede tomar una lista para aplicar varios métodos de agregación a la vez. Esto debería darte el resultado que necesitas:
df[['col1', 'col2', 'col3', 'col4']].groupby(['col1', 'col2']).agg(['mean', 'count'])
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-17 03:55:35
Respuesta rápida:
La forma más sencilla de obtener recuentos de filas por grupo es llamando a .size()
, que devuelve un Series
:
df.groupby(['col1','col2']).size()
Por lo general, desea este resultado como un DataFrame
(en lugar de un 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 ejemplo dataframe:
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
Entonces 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í: {[19]]}
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 I normalmente divido las estadísticas en agregaciones individuales que luego combino usando join
. Se ve así:
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 a pie de página
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 los recuentos de filas de grupo como una agregación independiente para cada columna. De lo contrario puede ser engañados en cuanto a cuántos registros se están utilizando realmente para calcular cosas como la media porque los pandas eliminarán NaN
entradas en el cálculo de la media sin informarle al respecto.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-30 06:35:52
Podemos hacerlo fácilmente usando groupby y count. Pero, debemos recordar usar reset_index ().
df[['col1','col2','col3','col4']].groupby(['col1','col2']).count().\
reset_index()
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-27 18:17:07