Pandas groupby para valores cero

Tengo datos como este en un archivo csv

Symbol,Action,Year AAPL,Buy,2001 AAPL,Buy,2001 BAC,Sell,2002 BAC,Sell,2002 

Soy capaz de leerlo y agruparme de esta manera.

 df.groupby(['Symbol','Year']).count() 

yo obtengo

  Action Symbol Year AAPL 2001 2 BAC 2002 2 

Deseo esto (el orden no importa)

  Action Symbol Year AAPL 2001 2 AAPL 2002 0 BAC 2001 0 BAC 2002 2 

Quiero saber si es posible contar para cero ocurrencias

Puedes usar pivot_table con unstack :

 print df.pivot_table(index='Symbol', columns='Year', values='Action', fill_value=0, aggfunc='count').unstack() Year Symbol 2001 AAPL 2 BAC 0 2002 AAPL 0 BAC 2 dtype: int64 

Si necesita salida como DataFrame use to_frame :

 print df.pivot_table(index='Symbol', columns='Year', values='Action', fill_value=0, aggfunc='count').unstack() .to_frame() .rename(columns={0:'Action'}) Action Year Symbol 2001 AAPL 2 BAC 0 2002 AAPL 0 BAC 2 

Puedes usar esto:

 df = df.groupby(['Symbol','Year']).count().unstack(fill_value=0).stack() print df 

Salida:

  Action Symbol Year AAPL 2001 2 2002 0 BAC 2001 0 2002 2 

Si desea hacer esto sin usar pivot_table, puede intentar el siguiente enfoque:

 midx = pd.MultiIndex.from_product([ df['Symbol'].unique(), df['Year'].unique()], names=['Symbol', 'Year']) df_grouped_by = df_grouped_by.reindex(midx, fill_value=0) 

Básicamente, lo que estamos haciendo anteriormente es crear un índice múltiple de todos los valores posibles multiplicando las dos columnas y luego usar ese índice múltiple para llenar los ceros en nuestro dataframe de grupo por grupo.

Paso 1: Cree un dataframe que almacene el recuento de cada clase que no sea cero en los recuentos de la columna

 count_df = df.groupby(['Symbol','Year']).size().reset_index(name='counts') 

Paso 2: ahora use pivot_table para obtener el dataframe deseado con conteos para las clases existentes y no existentes.

 df_final = pd.pivot_table(count_df, index=['Symbol','Year'], values='counts', fill_value = 0, dropna=False, aggfunc=np.sum) 

Ahora los valores de los conteos se pueden extraer como una lista con el comando

 list(df_final['counts'])