Как суммировать значения, сгруппированные по двум столбцам в пандах

21

У меня есть Pandas DataFrame, как это:

df = pd.DataFrame({
    'Date': ['2017-1-1', '2017-1-1', '2017-1-2', '2017-1-2', '2017-1-3'],
    'Groups': ['one', 'one', 'one', 'two', 'two'],
    'data': range(1, 6)})

    Date      Groups     data  
0  2017-1-1    one       1
1  2017-1-1    one       2
2  2017-1-2    one       3
3  2017-1-2    two       4
4  2017-1-3    two       5

Как я могу сгенерировать новый DataFrame, как это:

    Date       one     two 
0  2017-1-1    3        0
1  2017-1-2    3        4
2  2017-1-3    0        5
Kevin
источник

Ответы:

16

pivot_table было сделано для этого:

df.pivot_table(index='Date',columns='Groups',aggfunc=sum)

результаты в

         data
Groups    one  two
Date
2017-1-1  3.0  NaN
2017-1-2  3.0  4.0
2017-1-3  NaN  5.0

Лично я считаю, что этот подход намного проще для понимания и, безусловно, более питонен, чем сложная групповая операция. Затем, если вы хотите указать формат, вы можете просто привести его в порядок:

df.fillna(0,inplace=True)
df.columns = df.columns.droplevel()
df.columns.name = None
df.reset_index(inplace=True)

что дает вам

       Date  one  two
0  2017-1-1  3.0  0.0
1  2017-1-2  3.0  4.0
2  2017-1-3  0.0  5.0
Джош Д.
источник
1
Ницца! Это должен быть принятый ответ.
Туомастик
@ Джош Д. Это круто и просто! Я согласен с тем, что для того, чтобы понять, как работает группа, требуется определенная мозговая сила. Спасибо!
Кевин
8

Панды черной магии:

df = df.groupby(['Date', 'Groups']).sum().sum(
    level=['Date', 'Groups']).unstack('Groups').fillna(0).reset_index()

# Fix the column names
df.columns = ['Date', 'one', 'two']

В результате df:

       Date  one  two
0  2017-1-1  3.0  0.0
1  2017-1-2  3.0  4.0
2  2017-1-3  0.0  5.0
tuomastik
источник
Святой! Черная магия такая мощная! Большое спасибо!
Кевин
Пожалуйста! Смотрите обновленный ответ; Я упростил выражение и добавил исправление для имен столбцов, которые будут точно соответствовать запросу.
туомастик
Я думаю, что ваша предыдущая версия имеет свое преимущество, поскольку она может применяться к другим, более сложным наборам данных. Я скопировал его здесь: df.groupby (['Date', 'Groups', 'data']) ['data']. Sum (). Sum (level = ['Date', 'Groups']). Unstack ( «Группы»). Fillna (0)
Кевин
@Kevin Если этот или любой будущий ответ решил вашу проблему, примите ответ.
Туомастик