multiple groupby example columns python pandas dataframe group-by multi-index

python - example - pandas groupby count



Convertir un objeto Pandas GroupBy a DataFrame (8)

Abajo la solución puede ser más simple:

df1.reset_index().groupby( [ "Name", "City"],as_index=False ).count()

Estoy empezando con datos de entrada como este

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

Que cuando se imprime aparece así:

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

La 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 eventualmente 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 puedo ver cómo lograr esto en la documentación de los pandas. Cualquier consejo sería bienvenido.


Encontré 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()


Estas soluciones solo funcionaron parcialmente para mí porque estaba haciendo múltiples agregaciones. Aquí hay una salida de muestra de mi agrupado por la que quería convertir a un marco de datos:

Como quería más que el recuento proporcionado por reset_index (), escribí un método manual para convertir la imagen de arriba en un marco de datos. Entiendo que esta no es la forma más pitón / pandas de hacer esto, ya que es bastante detallada y explícita, pero era todo lo que necesitaba. Básicamente, use el método reset_index () explicado anteriormente para iniciar un marco de datos de "andamiaje", luego recorra los emparejamientos de grupos en el marco de datos agrupado, recupere los índices, realice sus cálculos contra el marco de datos no agrupado y establezca el valor en su nuevo marco de datos agregado .

df_grouped = df[[''Salary Basis'', ''Job Title'', ''Hourly Rate'', ''Male Count'', ''Female Count'']] df_grouped = df_grouped.groupby([''Salary Basis'', ''Job Title''], as_index=False) # Grouped gives us the indices we want for each grouping # We cannot convert a groupedby object back to a dataframe, so we need to do it manually # Create a new dataframe to work against df_aggregated = df_grouped.size().to_frame(''Total Count'').reset_index() df_aggregated[''Male Count''] = 0 df_aggregated[''Female Count''] = 0 df_aggregated[''Job Rate''] = 0 def manualAggregations(indices_array): temp_df = df.iloc[indices_array] return { ''Male Count'': temp_df[''Male Count''].sum(), ''Female Count'': temp_df[''Female Count''].sum(), ''Job Rate'': temp_df[''Hourly Rate''].max() } for name, group in df_grouped: ix = df_grouped.indices[name] calcDict = manualAggregations(ix) for key in calcDict: #Salary Basis, Job Title columns = list(name) df_aggregated.loc[(df_aggregated[''Salary Basis''] == columns[0]) & (df_aggregated[''Job Title''] == columns[1]), key] = calcDict[key]

Si un diccionario no es lo tuyo, los cálculos podrían aplicarse en línea en el bucle for:

df_aggregated[''Male Count''].loc[(df_aggregated[''Salary Basis''] == columns[0]) & (df_aggregated[''Job Title''] == columns[1])] = df[''Male Count''].iloc[ix].sum()


He agregado con datos de Qtywise y almaceno a dataframe

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


Quiero cambiar ligeramente la respuesta dada por Wes, porque la versión 0.16.2 requiere as_index=False . Si no lo configura, obtiene un marco de datos vacío.

Source :

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

Al pasar as_index=False se devolverán los grupos sobre los que se está agregando, si se denominan columnas.

Las funciones de agregación son aquellas 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 haces, por ejemplo, DataFrame.sum() y recuperas una Series .

Puede actuar como un reductor o un filtro, consulte 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 #

EDITAR:

En la versión 0.17.1 y posterior, puede usar un subset en count y reset_index con el name parámetro 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 el size cuenta los valores de NaN mientras que el count no.


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 () extrae el recuento único de groupby, y el método reset_index () restablece el nombre de la columna que desea que sea. Finalmente, se llama a la función Pandas Dataframe () para crear el objeto DataFrame.


Tal vez entiendo mal la pregunta, pero si desea convertir el grupo de nuevo a un marco de datos, puede usar .to_frame (). Quería restablecer el índice cuando hice esto, así que también incluí esa parte.

código de ejemplo no relacionado con la pregunta

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


g1 aquí hay un DataFrame. Sin embargo, tiene un índice jerárquico:

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 quieres 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