Pandas grupo por sum acumulativa

Me gustaría agregar una columna de sum acumulativa a mi dataframe de Pandas para que:

name | day | no -----|-----------|---- Jack | Monday | 10 Jack | Tuesday | 20 Jack | Tuesday | 10 Jack | Wednesday | 50 Jill | Monday | 40 Jill | Wednesday | 110 

se convierte en:

 Jack | Monday | 10 | 10 Jack | Tuesday | 30 | 40 Jack | Wednesday | 50 | 90 Jill | Monday | 40 | 40 Jill | Wednesday | 110 | 150 

df.groupby varios combos de df.groupby y df.agg(lambda x: cumsum(x)) en vano.

Esto debería hacerlo, necesita groupby() dos veces.

 In [52]: print df name day no 0 Jack Monday 10 1 Jack Tuesday 20 2 Jack Tuesday 10 3 Jack Wednesday 50 4 Jill Monday 40 5 Jill Wednesday 110 In [53]: print df.groupby(by=['name','day']).sum().groupby(level=[0]).cumsum() no name day Jack Monday 10 Tuesday 40 Wednesday 90 Jill Monday 40 Wednesday 150 

Tenga en cuenta, el DataFrame resultante tiene MultiIndex .

Esto funciona en pandas 0.16.2.

 In[23]: print df name day no 0 Jack Monday 10 1 Jack Tuesday 20 2 Jack Tuesday 10 3 Jack Wednesday 50 4 Jill Monday 40 5 Jill Wednesday 110 In[24]: df['no_cumulative'] = df.groupby(['name'])['no'].apply(lambda x: x.cumsum()) In[25]: print df name day no no_cumulative 0 Jack Monday 10 10 1 Jack Tuesday 20 30 2 Jack Tuesday 10 40 3 Jack Wednesday 50 90 4 Jill Monday 40 40 5 Jill Wednesday 110 150 

Modificación a la respuesta de @Dmitry. Esto es más simple y funciona en pandas 0.19.0:

 print(df) name day no 0 Jack Monday 10 1 Jack Tuesday 20 2 Jack Tuesday 10 3 Jack Wednesday 50 4 Jill Monday 40 5 Jill Wednesday 110 df['no_csum'] = df.groupby(['name'])['no'].cumsum() print(df) name day no no_csum 0 Jack Monday 10 10 1 Jack Tuesday 20 30 2 Jack Tuesday 10 40 3 Jack Wednesday 50 90 4 Jill Monday 40 40 5 Jill Wednesday 110 150 

En lugar de df.groupby(by=['name','day']).sum().groupby(level=[0]).cumsum() (ver arriba) también puede hacer un df.set_index(['name', 'day']).groupby(level=0, as_index=False).cumsum()

  • df.groupby(by=['name','day']).sum() realidad está moviendo ambas columnas a un MultiIndex
  • as_index=False significa que no necesita llamar a reset_index después

Deberías usar

 df['cum_no'] = df.no.cumsum() 

http://pandas.pydata.org/pandas-docs/version/0.19.2/generated/pandas.DataFrame.cumsum.html

Otra forma de hacerlo.

 import pandas as pd df = pd.DataFrame({'C1' : ['a','a','a','b','b'], 'C2' : [1,2,3,4,5]}) df['cumsum'] = df.groupby(by=['C1'])['C2'].transform(lambda x: x.cumsum()) df 

introduzca la descripción de la imagen aquí