Pandas DataFrame Group por dos columnas y obtener recuentos


166

Tengo un marco de datos de pandas en el siguiente formato:

df = pd.DataFrame([[1.1, 1.1, 1.1, 2.6, 2.5, 3.4,2.6,2.6,3.4,3.4,2.6,1.1,1.1,3.3], list('AAABBBBABCBDDD'), [1.1, 1.7, 2.5, 2.6, 3.3, 3.8,4.0,4.2,4.3,4.5,4.6,4.7,4.7,4.8], ['x/y/z','x/y','x/y/z/n','x/u','x','x/u/v','x/y/z','x','x/u/v/b','-','x/y','x/y/z','x','x/u/v/w'],['1','3','3','2','4','2','5','3','6','3','5','1','1','1']]).T
df.columns = ['col1','col2','col3','col4','col5']

df:

   col1 col2 col3     col4 col5
0   1.1    A  1.1    x/y/z    1
1   1.1    A  1.7      x/y    3
2   1.1    A  2.5  x/y/z/n    3
3   2.6    B  2.6      x/u    2
4   2.5    B  3.3        x    4
5   3.4    B  3.8    x/u/v    2
6   2.6    B    4    x/y/z    5
7   2.6    A  4.2        x    3
8   3.4    B  4.3  x/u/v/b    6
9   3.4    C  4.5        -    3
10  2.6    B  4.6      x/y    5
11  1.1    D  4.7    x/y/z    1
12  1.1    D  4.7        x    1
13  3.3    D  4.8  x/u/v/w    1

Ahora quiero agrupar esto por dos columnas como las siguientes:

df.groupby(['col5','col2']).reset_index()

Salida:

             index col1 col2 col3     col4 col5
col5 col2                                      
1    A    0      0  1.1    A  1.1    x/y/z    1
     D    0     11  1.1    D  4.7    x/y/z    1
          1     12  1.1    D  4.7        x    1
          2     13  3.3    D  4.8  x/u/v/w    1
2    B    0      3  2.6    B  2.6      x/u    2
          1      5  3.4    B  3.8    x/u/v    2
3    A    0      1  1.1    A  1.7      x/y    3
          1      2  1.1    A  2.5  x/y/z/n    3
          2      7  2.6    A  4.2        x    3
     C    0      9  3.4    C  4.5        -    3
4    B    0      4  2.5    B  3.3        x    4
5    B    0      6  2.6    B    4    x/y/z    5
          1     10  2.6    B  4.6      x/y    5
6    B    0      8  3.4    B  4.3  x/u/v/b    6

Quiero obtener el recuento de cada fila como sigue. Rendimiento esperado:

col5 col2 count
1    A      1
     D      3
2    B      2
etc...

¿Cómo obtener mi salida esperada? ¿Y quiero encontrar el recuento más grande para cada valor 'col2'?


Una pregunta muy similar acaba de surgir ayer ... mira aquí .
bdiamante

Respuestas:


116

Seguido de la respuesta de @ Andy, puede hacer lo siguiente para resolver su segunda pregunta:

In [56]: df.groupby(['col5','col2']).size().reset_index().groupby('col2')[[0]].max()
Out[56]: 
      0
col2   
A     3
B     2
C     1
D     3

1
¿Puedo obtener valores "col5" para esto como C ... 1 ... 3?
Nilani Algiriyage

141

Usted está buscando size:

In [11]: df.groupby(['col5', 'col2']).size()
Out[11]:
col5  col2
1     A       1
      D       3
2     B       2
3     A       3
      C       1
4     B       1
5     B       2
6     B       1
dtype: int64

Para obtener la misma respuesta que waitingkuo (la "segunda pregunta"), pero un poco más limpia, es agrupar por nivel:

In [12]: df.groupby(['col5', 'col2']).size().groupby(level=1).max()
Out[12]:
col2
A       3
B       2
C       1
D       3
dtype: int64

1
No sé Por qué olvidé esto: O, de todos modos, ¿qué pasa con mi segunda pregunta? ¿Encontrar el conteo más grande para cada valor "col2" y obtener el valor "col5" correspondiente?
Nilani Algiriyage

23

Insertar datos en un marco de datos de pandas y proporcionar el nombre de la columna .

import pandas as pd
df = pd.DataFrame([['A','C','A','B','C','A','B','B','A','A'], ['ONE','TWO','ONE','ONE','ONE','TWO','ONE','TWO','ONE','THREE']]).T
df.columns = [['Alphabet','Words']]
print(df)   #printing dataframe.

Estos son nuestros datos impresos:

ingrese la descripción de la imagen aquí

Para hacer un grupo de marco de datos en pandas y contador ,
debe proporcionar una columna más que cuente la agrupación, llamemos a esa columna como "CONTADOR" en el marco de datos .

Me gusta esto:

df['COUNTER'] =1       #initially, set that counter to 1.
group_data = df.groupby(['Alphabet','Words'])['COUNTER'].sum() #sum function
print(group_data)

SALIDA:

ingrese la descripción de la imagen aquí


9
¿Cómo puedo hacer que la columna Alfabeto (por ejemplo, A) se repita a continuación y no dejar los espacios en la primera columna?
blissweb

¿Cómo acceder al valor de cada grupo que es la suma basada en el alfabeto y la palabra?
Rahul Goyal

21

Solución idiomática que usa solo un grupo

(df.groupby(['col5', 'col2']).size() 
   .sort_values(ascending=False) 
   .reset_index(name='count') 
   .drop_duplicates(subset='col2'))

  col5 col2  count
0    3    A      3
1    1    D      3
2    5    B      2
6    3    C      1

Explicación

El resultado del sizemétodo groupby es una Serie con col5y col2en el índice. Desde aquí, puede usar otro método groupby para encontrar el valor máximo de cada valor, col2pero no es necesario hacerlo. Simplemente puede ordenar todos los valores de mantener a descender y luego sólo las filas con la primera aparición de col2la drop_duplicatesmétodo.


No hay ningún parámetro llamado nameen reset_index()la versión actual de pandas: pandas.pydata.org/pandas-docs/stable/generated/…
mmBs


Ok, mi mal Lo usé cuando trabajaba con DataFrameno Series. Gracias por el enlace.
mmBs

2

Si desea agregar una nueva columna (por ejemplo, 'cuenta_columna') que contiene los recuentos de los grupos en el marco de datos:

df.count_column=df.groupby(['col5','col2']).col5.transform('count')

(Elegí 'col5' ya que no contiene nan)


-2

Puede usar el recuento de funciones incorporado seguido de la función groupby

df.groupby(['col5','col2']).count()
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.