2012-04-29 22 views
231

estoy empezando con los datos de entrada como estala conversión de un objeto pandas GroupBy de trama de datos

df1 = pandas.DataFrame({ 
    "Name" : ["Alice", "Bob", "Mallory", "Mallory", "Bob" , "Mallory"] , 
    "City" : ["Seattle", "Seattle", "Portland", "Seattle", "Seattle", "Portland"] }) 

Lo cual, impreso aparece como esto:

City  Name 
0 Seattle Alice 
1 Seattle  Bob 
2 Portland Mallory 
3 Seattle Mallory 
4 Seattle  Bob 
5 Portland Mallory 

agrupación es bastante simple:

g1 = df1.groupby([ "Name", "City"]).count() 

y la impresión produce un objeto GroupBy:

    City Name 
Name City 
Alice Seattle  1  1 
Bob  Seattle  2  2 
Mallory Portland  2  2 
     Seattle  1  1 

Pero lo que quiero con el tiempo es otro objeto DataFrame que contenga todas las filas en el objeto GroupBy. En otras palabras, quiero obtener el siguiente resultado:

    City Name 
Name City 
Alice Seattle  1  1 
Bob  Seattle  2  2 
Mallory Portland  2  2 
Mallory Seattle  1  1 

No veo exactamente cómo lograr esto en la documentación de los pandas. Cualquier sugerencia sería bienvenida.

Respuesta

301

g1 aquí es a DataFrame. Tiene un índice jerárquico, sin embargo:

In [19]: type(g1) 
Out[19]: pandas.core.frame.DataFrame 

In [20]: g1.index 
Out[20]: 
MultiIndex([('Alice', 'Seattle'), ('Bob', 'Seattle'), ('Mallory', 'Portland'), 
     ('Mallory', 'Seattle')], dtype=object) 

Tal vez usted quiere algo como esto?

In [21]: g1.add_suffix('_Count').reset_index() 
Out[21]: 
     Name  City City_Count Name_Count 
0 Alice Seattle   1   1 
1  Bob Seattle   2   2 
2 Mallory Portland   2   2 
3 Mallory Seattle   1   1 

O algo como:

In [36]: DataFrame({'count' : df1.groupby([ "Name", "City"]).size()}).reset_index() 
Out[36]: 
     Name  City count 
0 Alice Seattle  1 
1  Bob Seattle  2 
2 Mallory Portland  2 
3 Mallory Seattle  1 
+6

Gran respuesta. El segundo caso que mostró con una sola columna de "recuento" fue * exactamente * lo que necesitaba. – saveenr

+6

'reset.index()' hace el trabajo, ¡genial! – gented

+16

Se podría haber utilizado:.. 'Df1.groupby ([ "Nombre", "City"]) .size() to_frame (name = 'count') reset_index()' –

65

Quiero pocos cambios poco respuesta por Wes, porque la versión 0.16.2 establece necesidad as_index=False. Si no lo configura, obtiene el marco de datos vacío.

Source:

funciones de agregación no devolverán los grupos que están sobre la agregación si se nombran columnas, cuando as_index=True, el valor predeterminado. Las columnas agrupadas serán los índices del objeto devuelto.

Pasando as_index=False devolverá los grupos que está agregando, si se nombran columnas.

Las funciones de adición son los que reducen la dimensión de los objetos devueltos, por ejemplo: mean, sum, size, count, std, var, sem, describe, first, last, nth, min, max. Esto es lo que sucede cuando lo haces, por ejemplo, DataFrame.sum() y obtienes un Series.

enésimo puede actuar como un reductor o un filtro, vea here.

import pandas as pd 

df1 = pd.DataFrame({"Name":["Alice", "Bob", "Mallory", "Mallory", "Bob" , "Mallory"], 
        "City":["Seattle","Seattle","Portland","Seattle","Seattle","Portland"]}) 
print df1 
# 
#  City  Name 
#0 Seattle Alice 
#1 Seattle  Bob 
#2 Portland Mallory 
#3 Seattle Mallory 
#4 Seattle  Bob 
#5 Portland Mallory 
# 
g1 = df1.groupby(["Name", "City"], as_index=False).count() 
print g1 
# 
#     City Name 
#Name City 
#Alice Seattle  1  1 
#Bob  Seattle  2  2 
#Mallory Portland  2  2 
#  Seattle  1  1 
# 

EDIT:

En la versión 0.17.1 y más tarde se puede utilizar subset en count y reset_index con el parámetro name en size:

print df1.groupby(["Name", "City"], as_index=False).count() 
#IndexError: list index out of range 

print df1.groupby(["Name", "City"]).count() 
#Empty DataFrame 
#Columns: [] 
#Index: [(Alice, Seattle), (Bob, Seattle), (Mallory, Portland), (Mallory, Seattle)] 

print df1.groupby(["Name", "City"])[['Name','City']].count() 
#     Name City 
#Name City     
#Alice Seattle  1  1 
#Bob  Seattle  2  2 
#Mallory Portland  2  2 
#  Seattle  1  1 

print df1.groupby(["Name", "City"]).size().reset_index(name='count') 
#  Name  City count 
#0 Alice Seattle  1 
#1  Bob Seattle  2 
#2 Mallory Portland  2 
#3 Mallory Seattle  1 

La diferencia entre count y size es que size cuenta los valores de NaN mientras count no.

+6

Creo que esta es la manera más fácil: un trazador de líneas que utiliza el buen hecho de que puede nombrar la columna de la serie con reset_index: '' 'df1.groupby ([" Nombre "," Ciudad "]). Tamaño(). Reset_index (name = "count") '' ' – Ben

+0

¿Hay alguna razón por la cual' as_index = False 'dejó de funcionar en las últimas versiones? También traté de ejecutar 'df1.groupby ([" Nombre "," Ciudad "], as_index = False) .size()' pero no afecta el resultado (probablemente porque el resultado de la agrupación es 'Serie' no' DataFrame' –

+1

no estoy seguro, pero parece que sólo hay 2 columnas y 'groupby' por estas columnas, pero no estoy seguro, porque no soy pandas desarrollador – jezrael

4

Encontré que esto funcionó para mí.

import numpy as np 
import pandas as pd 

df1 = pd.DataFrame({ 
    "Name" : ["Alice", "Bob", "Mallory", "Mallory", "Bob" , "Mallory"] , 
    "City" : ["Seattle", "Seattle", "Portland", "Seattle", "Seattle", "Portland"]}) 

df1['City_count'] = 1 
df1['Name_count'] = 1 

df1.groupby(['Name', 'City'], as_index=False).count() 
5

Simplemente, esto debería hacer la tarea:

import pandas as pd 

grouped_df = df1.groupby([ "Name", "City"]) 

pd.DataFrame(grouped_df.size().reset_index(name = "Group_Count")) 

Aquí, grouped_df.size() detiene el conteo GroupBy única, y reset_index() método restablece el nombre de la columna que desea que ser. Finalmente, se llama a la función pandas Dataframe() para crear el objeto DataFrame.

+0

salida del método .to_frame():.. grouped_df.size() .to_frame ('Group_Count') – Sealander

3

Tal vez entienden mal la pregunta, pero si usted desea convertir el GroupBy de nuevo a una trama de datos se puede utilizar .to_frame(). Quería restablecer el índice cuando lo hice, así que incluí esa parte también.

código de ejemplo sin relación a la pregunta

df = df['TIME'].groupby(df['Name']).min() 
df = df.to_frame() 
df = df.reset_index(level=['Name',"TIME"]) 
1

Me han incrementado por las Cant de datos inteligentes y tienda para trama de datos

almo_grp_data = pd.DataFrame({'Qty_cnt' : 
almo_slt_models_data.groupby(['orderDate','Item','State Abv'] 
     )['Qty'].sum()}).reset_index() 
Cuestiones relacionadas