Cómo imprimir un objeto groupby

133

Quiero imprimir el resultado de la agrupación con Pandas.

Tengo un marco de datos:

import pandas as pd
df = pd.DataFrame({'A': ['one', 'one', 'two', 'three', 'three', 'one'], 'B': range(6)})
print(df)

       A  B
0    one  0
1    one  1
2    two  2
3  three  3
4  three  4
5    one  5

Al imprimir después de agrupar por 'A' tengo lo siguiente:

print(df.groupby('A'))

<pandas.core.groupby.DataFrameGroupBy object at 0x05416E90>

¿Cómo puedo imprimir el marco de datos agrupado?

Si lo hago:

print(df.groupby('A').head())

Obtengo el marco de datos como si no estuviera agrupado:

             A  B
A                
one   0    one  0
      1    one  1
two   2    two  2
three 3  three  3
      4  three  4
one   5    one  5

Estaba esperando algo como:

             A  B
A                
one   0    one  0
      1    one  1
      5    one  5
two   2    two  2
three 3  three  3
      4  three  4
usuario3465658
fuente
Estoy obteniendo la salida correcta con print df.groupby('A').head(). ¿Qué versión de pandas tienes?
Amit Verma
Acabo de actualizar a 0.13.1 en mi computadora de escritorio y portátil.
user3465658
1
¿Qué tal "listar ()" el ​​objeto directamente? Y luego puede manipularlo / imprimirlo como una estructura de datos normal.
Tropicpenguin
Por lo que puedo decir, ni una sola respuesta logra producir el resultado deseado. Para este ejemplo específico, lo más cercano que pude encontrar fue df.groupby(['A', 'B']).sum(), pero fallaría si los ('A', 'B')pares no son únicos.
Eric Duminil

Respuestas:

100

Simplemente haz:

grouped_df = df.groupby('A')

for key, item in grouped_df:
    print(grouped_df.get_group(key), "\n\n")

Esto también funciona

grouped_df = df.groupby('A')    
gb = grouped_df.groups

for key, values in gb.iteritems():
    print(df.ix[values], "\n\n")

Para la agrupación selectiva de claves: inserte las claves que desee dentro de las key_list_from_gbsiguientes, utilizando gb.keys(): Por ejemplo

gb = grouped_df.groups
gb.keys()

key_list_from_gb = [key1, key2, key3]

for key, values in gb.items():
    if key in key_list_from_gb:
        print(df.ix[values], "\n")
Surya
fuente
1
Otra opción es:for A in d['A'].unique(): print(A, df.query(f'A == "{A}"'))
tommy.carstensen
__iter __ () también funciona. Devuelve la secuencia de generación del generador de (nombre, objeto subconjunto) para cada grupo
Jeremy Z
¿Por qué no dar la vuelta key_list_from_gb?
pfnuesel
66

Si simplemente está buscando una forma de mostrarlo, puede usar describe ():

grp = df.groupby['colName']
grp.describe()

Esto te da una mesa ordenada.

Swagath
fuente
66
Es una mesa ordenada pero no es la mesa deseada.
Eric Duminil
15

Confirmé que el comportamiento de los head()cambios entre la versión 0.12 y 0.13. Eso me parece un error. Creé un problema .

Pero una operación groupby en realidad no devuelve un DataFrame ordenado por grupo. El .head()método es un poco engañoso aquí: es solo una característica conveniente que le permite volver a examinar el objeto (en este caso df) que agrupó. El resultado de groupbyes un tipo de objeto separado, un GroupByobjeto. Debe apply, transformo filterpara volver a un DataFrame o Series.

Si todo lo que quería hacer era ordenar por los valores en las columnas A, debería usar df.sort('A').

Dan Allan
fuente
44
Tenga en cuenta que en headrealidad está haciendo head(5)iow, está mostrando las primeras 5 filas, más correcto para 'mostrar' el marco df.groupby('A').apply(lambda x: x), que es efectivamente un passthru. Supongo que podrías tener un pass()método, tal vez.
Jeff
13

Otra alternativa simple:

for name_of_the_group, group in grouped_dataframe:
   print (name_of_the_group)
   print (group)
Sumit Pokhrel
fuente
9

Además, otra alternativa simple podría ser:

gb = df.groupby("A")
gb.count() # or,
gb.get_group(your_key)
Surya
fuente
7

Además de las respuestas anteriores:

Tomando tu ejemplo,

df = pd.DataFrame({'A': ['one', 'one', 'two', 'three', 'three', 'one'], 'B': range(6)})

Luego simple código de 1 línea

df.groupby('A').apply(print)
QPeiran
fuente
4

Gracias a Surya por sus buenas ideas. Limpiaría su solución y simplemente haría:

for key, value in df.groupby('A'):
    print(key, value)
mimoralea
fuente
3

Lista de llamadas () en el objeto GroupBy

print(list(df.groupby('A')))

te dio:

[('one',      A  B
0  one  0
1  one  1
5  one  5), ('three',        A  B
3  three  3
4  three  4), ('two',      A  B
2  two  2)]
Elizabeth Orrico
fuente
Sí, esto necesita más votos! También puede hacer esto después de agrupar el objeto. df_g = df.groupby ('A'), entonces puede llamar a la lista (df_g) o si solo desea la primera lista de llamadas grupales (df_g) [0]. Esto es una cosa que me gusta de R sobre Python. En R no tiene que recorrer la mayoría de los objetos para ver los datos, pero Python debe hacerlo en muchos de los objetos. Encontrar procesos como este es refrescante. Gracias Elizabeth
PVic
2

no puede ver los datos groupBy directamente mediante la declaración de impresión, pero puede ver iterando sobre el grupo usando for loop intente este código para ver el grupo por datos

group = df.groupby('A') #group variable contains groupby data
for A,A_df in group: # A is your column and A_df is group of one kind at a time
  print(A)
  print(A_df)

obtendrá un resultado después de intentar esto como un grupo por resultado

Espero que ayude

Praveen Kumar
fuente
2

En Jupyter Notebook, si hace lo siguiente, imprime una buena versión agrupada del objeto. El applymétodo ayuda en la creación de un marco de datos de múltiples índices.

by = 'A'  # groupby 'by' argument
df.groupby(by).apply(lambda a: a[:])

Salida:

             A  B
A                
one   0    one  0
      1    one  1
      5    one  5
three 3  three  3
      4  three  4
two   2    two  2

Si desea que las bycolumnas no aparezcan en la salida, simplemente suelte las columnas, así.

df.groupby(by).apply(lambda a: a.drop(by, axis=1)[:])

Salida:

         B
A         
one   0  0
      1  1
      5  5
three 3  3
      4  4
two   2  2

Aquí, no estoy seguro de por qué .iloc[:]no funciona en lugar de [:]al final. Entonces, si hay algunos problemas en el futuro debido a actualizaciones (o en la actualidad), .iloc[:len(a)]también funciona.

Barnik Biswas
fuente
0

Encontré una forma complicada, solo para una lluvia de ideas, vea el código:

df['a'] = df['A']  # create a shadow column for MultiIndexing
df.sort_values('A', inplace=True)
df.set_index(["A","a"], inplace=True)
print(df)

La salida:

             B
A     a
one   one    0
      one    1
      one    5
three three  3
      three  4
two   two    2

Los pros son tan fáciles de imprimir, ya que devuelve un marco de datos, en lugar de Groupby Object. Y la salida se ve bien. Si bien la desventaja es que crea una serie de datos redundantes.

Sheng Zhuang
fuente
0

En python 3

k = None
for name_of_the_group, group in dict(df_group):
    if(k != name_of_the_group):
        print ('\n', name_of_the_group)
        print('..........','\n')
    print (group)
    k = name_of_the_group

De manera más interactiva

Deepanshu Mehta
fuente
-2

para imprimir todas (o arbitrariamente muchas) líneas del df agrupado:

import pandas as pd
pd.set_option('display.max_rows', 500)

grouped_df = df.group(['var1', 'var2'])
print(grouped_df)
randomWalk112358
fuente