Как использовать группировку в Pandas для получения суммы?

Вопрос или проблема

Я использую этот DataFrame:

Фрукты   Дата      Имя  Количество
Яблоки  10/6/2016 Боб    7
Яблоки  10/6/2016 Боб    8
Яблоки  10/6/2016 Майк   9
Яблоки  10/7/2016 Стив 10
Яблоки  10/7/2016 Боб    1
Апельсины 10/7/2016 Боб    2
Апельсины 10/6/2016 Том   15
Апельсины 10/6/2016 Майк  57
Апельсины 10/6/2016 Боб   65
Апельсины 10/7/2016 Тони   1
Виноград  10/7/2016 Боб    1
Виноград  10/7/2016 Том   87
Виноград  10/7/2016 Боб   22
Виноград  10/7/2016 Боб   12
Виноград  10/7/2016 Тони  15

Я хотел бы агрегировать это по Имя, а затем по Фрукты, чтобы получить общее количество Фруктов на Имя. Например:

Боб,Яблоки,16

Я пытался сгруппировать по Имя и Фрукты, но как мне получить общее количество Фруктов?

Используйте GroupBy.sum:

df.groupby(['Фрукты','Имя']).sum()

Out[31]: 
               Количество
Фрукты   Имя         
Яблоки  Боб        16
        Майк        9
        Стив      10
Виноград  Боб        35
        Том        87
        Тони       15
Апельсины Боб        67
        Майк       57
        Том        15
        Тони        1

Чтобы указать столбец для суммирования, используйте: df.groupby(['Имя', 'Фрукты'])['Количество'].sum()

Также вы можете использовать функцию agg,

df.groupby(['Имя', 'Фрукты'])['Количество'].agg('sum')

Если вы хотите сохранить исходные столбцы Фрукты и Имя, используйте reset_index(). В противном случае Фрукты и Имя станут частью индекса.

df.groupby(['Фрукты','Имя'])['Количество'].sum().reset_index()

Фрукты   Имя       Количество
Яблоки  Боб        16
Яблоки  Майк        9
Яблоки  Стив      10
Виноград  Боб        35
Виноград  Том        87
Виноград  Тони       15
Апельсины Боб        67
Апельсины Майк       57
Апельсины Том        15
Апельсины Тони        1

Как видно из других ответов:

df.groupby(['Фрукты','Имя'])['Количество'].sum()

               Количество
Фрукты   Имя         
Яблоки  Боб        16
        Майк        9
        Стив      10
Виноград  Боб        35
        Том        87
        Тони       15
Апельсины Боб        67
        Майк       57
        Том        15
        Тони        1

Все остальные ответы достигают того, что вы хотите.

Вы можете использовать функциональность pivot, чтобы организовать данные в красивую таблицу

df.groupby(['Фрукты','Имя'],as_index = False).sum().pivot('Фрукты','Имя').fillna(0)

Имя    Боб     Майк    Стив   Том    Тони
Фрукты                   
Яблоки  16.0    9.0     10.0    0.0     0.0
Виноград  35.0    0.0     0.0     87.0    15.0
Апельсины 67.0    57.0    0.0     15.0    1.0

df.groupby(['Фрукты','Имя'])['Количество'].sum()

Вы можете выбирать разные столбцы для суммирования чисел.

Вариация функции .agg(); предоставляет возможность (1) сохранять тип DataFrame, (2) применять средние значения, подсчеты, суммы и т.д. и (3) позволяет группировать по нескольким столбцам, сохраняя удобочитаемость.

df.groupby(['att1', 'att2']).agg({'att1': "count", 'att3': "sum",'att4': 'mean'})

используя ваши значения…

df.groupby(['Имя', 'Фрукты']).agg({'Количество': "sum"})

Вы можете установить столбец groupby в index, а затем использовать sum с level

df.set_index(['Фрукты','Имя']).sum(level=[0,1])
Out[175]: 
               Количество
Фрукты   Имя         
Яблоки  Боб        16
        Майк        9
        Стив      10
Апельсины Боб        67
        Том        15
        Майк       57
        Тони       1
Виноград  Боб        35
        Том        87
        Тони       15

Вы также можете использовать transform() на столбце Количество после группировки. Эта операция вычисляет общее количество в одной группе с функцией sum, результатом является серия с тем же индексом, что и у оригинального DataFrame.

df['Количество'] = df.groupby(['Фрукты', 'Имя'])['Количество'].transform('sum')
df = df.drop_duplicates(subset=['Фрукты', 'Имя']).drop('Дата', 1)

Затем вы можете удалить дублирующиеся строки по столбцам Фрукты и Имя. Более того, вы можете удалить столбец Дата, указав ось 1 (0 для строк и 1 для столбцов).

# print(df)

      Фрукты   Имя  Количество
0    Яблоки    Боб      16
2    Яблоки   Майк       9
3    Яблоки  Стив      10
5   Апельсины    Боб      67
6   Апельсины    Том      15
7   Апельсины   Майк      57
9   Апельсины   Тони      1
10   Виноград    Боб      35
11   Виноград    Том      87
14   Виноград   Тони      15

# Вы можете добиться такого же результата с функциями, обсужденными другими: 
# print(df.groupby(['Фрукты', 'Имя'], as_index=False)['Количество'].sum())
# print(df.groupby(['Фрукты', 'Имя'], as_index=False)['Количество'].agg('sum'))

Существует официальный учебник Группировка: разбить-применить-объединить, который рассказывает о том, что вы можете делать после группировки.

Если вы хотите, чтобы агрегированный столбец имел пользовательское имя, такое как Общее количество, Итого и т.д. (все решения здесь приводят к DataFrame, в котором агрегированный столбец называется Количество), используйте именованную агрегацию:

df.groupby(['Фрукты', 'Имя'], as_index=False).agg(**{'Общее количество': ('Количество', 'sum')})

или (если пользовательское имя не требует пробелов):

df.groupby(['Фрукты', 'Имя'], as_index=False).agg(Общее=('Количество', 'sum'))

это эквивалентно SQL запросу:

SELECT Фрукты, Имя, sum(Количество) AS Общее
FROM df 
GROUP BY Фрукты, Имя

Говоря о SQL, есть модуль pandasql, который позволяет вам запрашивать pandas DataFrame в локальной среде, используя синтаксис SQL. Он не является частью Pandas, поэтому его нужно установить отдельно.

#! pip install pandasql
from pandasql import sqldf
sqldf("""
SELECT Фрукты, Имя, sum(Количество) AS Общее
FROM df 
GROUP BY Фрукты, Имя
""")

Вы можете использовать reset_index(), чтобы сбросить индекс после суммы

df.groupby(['Фрукты','Имя'])['Количество'].sum().reset_index()

или

df.groupby(['Фрукты','Имя'], as_index=False)['Количество'].sum()

Вы можете использовать dfsql
для вашей задачи, это будет выглядеть примерно так:

df.sql('SELECT фрукт, sum(количество) GROUP BY фрукт')

https://github.com/mindsdb/dfsql

Вот статья об этом:

https://medium.com/riselab/why-every-data-scientist-using-pandas-needs-modin-bringing-sql-to-dataframes-3b216b29a7c0

Ответ или решение

Для агрегации данных в Pandas с использованием функции groupby, вам необходимо использовать метод, который позволит сгруппировать данные по определённым колонкам и затем применить операцию суммирования. В вашем случае вы хотите подсчитать общее количество каждого вида фруктов по каждому имени.

Сначала создадим DataFrame из ваших данных:

import pandas as pd

data = {
    'Fruit': ['Apples', 'Apples', 'Apples', 'Apples', 'Apples', 
              'Oranges', 'Oranges', 'Oranges', 'Oranges', 'Oranges',
              'Grapes', 'Grapes', 'Grapes', 'Grapes', 'Grapes'],
    'Date': ['10/6/2016', '10/6/2016', '10/6/2016', '10/7/2016', 
             '10/7/2016', '10/7/2016', '10/6/2016', '10/6/2016', 
             '10/6/2016', '10/7/2016', '10/7/2016', '10/7/2016', 
             '10/7/2016', '10/7/2016', '10/7/2016'],
    'Name': ['Bob', 'Bob', 'Mike', 'Steve', 'Bob', 
             'Bob', 'Tom', 'Mike', 'Bob', 'Tony', 
             'Bob', 'Tom', 'Bob', 'Bob', 'Tony'],
    'Number': [7, 8, 9, 10, 1, 
               2, 15, 57, 65, 1, 
               1, 87, 22, 12, 15]
}

df = pd.DataFrame(data)

Теперь давайте используем метод groupby для агрегации данных. В вашем случае, чтобы получить сумму по колонкам Fruit и Name, вы можете сделать следующее:

Метод 1: Простой groupby с sum()

result = df.groupby(['Fruit', 'Name'])['Number'].sum().reset_index()
print(result)

Метод 2: Использование метода agg()

Альтернативно, вы можете использовать метод agg(), который позволяет более гибко настраивать операции агрегации:

result = df.groupby(['Fruit', 'Name']).agg({'Number': 'sum'}).reset_index()
print(result)

Метод 3: С использованием именованной агрегации

Если вы хотите изменить имя итоговой колонки, можно использовать именованную агрегацию:

result = df.groupby(['Fruit', 'Name'], as_index=False).agg(Total=('Number', 'sum'))
print(result)

Метод 4: Создание сводной таблицы

Если вам нужно отобразить данные в формате таблицы, вы можете использовать метод pivot():

pivot_table = df.groupby(['Fruit', 'Name']).sum().unstack(fill_value=0)
print(pivot_table)

Важно

При использовании groupby, важно помнить, что по умолчанию индексы будут установлены на группы. Если вы хотите сохранить все колонки, вы можете использовать reset_index(), как показано в вышеупомянутых примерах.

Вы можете использовать любой из вышеперечисленных подходов, чтобы получить желаемые результаты. Применяйте метод, который наилучшим образом соответствует вашему сценарию.

Дополнительные ресурсы и официальная документация по методам агрегации и группировки в Pandas можно найти в официальной документации Pandas.

Оцените материал
Добавить комментарий

Капча загружается...