Вопрос или проблема
Я использую этот 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
Вот статья об этом:
Ответ или решение
Для агрегации данных в 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.