2017-01-23 10 views
4

Я потратил несколько часов, пытаясь сделать «кумулятивную группу по сумме» на кадре данных pandas. Я смотрел на все StackOverflow ответы и на удивление ни один из них не может решить мою (очень элементарное) проблема:Группа Pandas от cumsum keep colums

У меня есть dataframe:

df1 Out[8]: Name Date Amount 0 Jack 2016-01-31 10 1 Jack 2016-02-29 5 2 Jack 2016-02-29 8 3 Jill 2016-01-31 10 4 Jill 2016-02-29 5

Я пытаюсь

  1. группа по ['Name', 'Date'] и
  2. cumsum 'Amount'.
  3. То есть.

Так желаемый результат:

df1 Out[10]: Name Date Cumsum 0 Jack 2016-01-31 10 1 Jack 2016-02-29 23 2 Jill 2016-01-31 10 3 Jill 2016-02-29 15

EDIT: Я упрощая вопрос. С текущими ответами я до сих пор не могу получить правильную «бегущую» cumsum. Посмотрите внимательно, я хочу увидеть кумулятивную сумму «10, 23, 10, 15». На словах я хочу видеть каждую дату подряд общую кумулятивную сумму для человека. NB: Если для одного и того же человека есть две записи в одну дату, я хочу их суммировать, а затем добавить их в запущенную cumsum и только затем распечатать сумму.

Я ценю любые советы и/или помощь.

ответ

3

Вам нужно назначить выход на новый столбец, а затем удалить Amount колонку, drop:

df1['Cumsum'] = df1.groupby(by=['Name','Date'])['Amount'].cumsum() 
df1 = df1.drop('Amount', axis=1) 
print (df1) 
    Name  Date Cumsum 
0 Jack 2016-01-31  10 
1 Jack 2016-02-29  5 
2 Jack 2016-02-29  13 
3 Jill 2016-01-31  10 
4 Jill 2016-02-29  5 

Другое решение с assign:

df1 = df1.assign(Cumsum=df1.groupby(by=['Name','Date'])['Amount'].cumsum()) 
     .drop('Amount', axis=1) 
print (df1) 
    Name  Date Cumsum 
0 Jack 2016-01-31  10 
1 Jack 2016-02-29  5 
2 Jack 2016-02-29  13 
3 Jill 2016-01-31  10 
4 Jill 2016-02-29  5 

EDIT замечанием:

Первые groupby колонны Name и Date и агрегат sum, затем groupby от levelName и агрегат cumsum.

df = df1.groupby(by=['Name','Date'])['Amount'].sum() 
     .groupby(level='Name').cumsum().reset_index(name='Cumsum') 
print (df) 
    Name  Date Cumsum 
0 Jack 2016-01-31  10 
1 Jack 2016-02-29  23 
2 Jill 2016-01-31  10 
3 Jill 2016-02-29  15 
+0

Спасибо за ответ, однако вторая группа должна сваливать вместе несколько 2016-02-29 сумм Джека. Таким образом, Cumsum должен иметь только четыре строки с надписью «10, 23, 10, 15». Я постараюсь работать с тем, что вы предоставили, тем не менее, спасибо. – gmarais

+0

Пожалуйста, проверьте отредактированный ответ. – jezrael

+0

Гений! спасибо спасибо – gmarais

4

Сначала установите индекс, а затем groupby.

df.set_index(['Name', 'Date']).groupby(level=[0, 1]).Amount.cumsum().reset_index() 

enter image description here


После того, как ОП изменил свой вопрос, теперь это правильный ответ.

df1.groupby(
    ['Name','Date'] 
)Amount.sum().groupby(
    level='Name' 
).cumsum() 

Это тот же ответ обеспечивается jezrael

+0

Спасибо за ответ.Согласно моему правлению, ваше решение не дает желаемого результата, однако я считаю, что вы обеспечили хорошее направление. Спасибо – gmarais

+0

Кто бы ни дал мне понизить голос, пожалуйста, передумайте, как ОП изменил свой вопрос после того, как был дан ответ. Я не хотел появляться, чтобы скопировать ответ Джераэля, поэтому я просто упомянул об этом. – piRSquared

+0

Привет, piRSquared, я проигнорировал, потому что исходный желаемый результат (даже до EDIT) не был достигнут с вашим кодом - так что, по крайней мере, это не upvote imho. Однако в ретроспективе вы предоставили 'set_index', который решил мою второстепенную проблему, поэтому я буду повышать. Еще раз спасибо – gmarais