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 unaSeries
.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