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

#python #python-3.x #pandas #numpy #dataframe

#python #панды #фрейм данных #группировка по #агрегировать

Вопрос:

Я использую этот фрейм данных:

 Fruit   Date      Name  Number
Apples  10/6/2016 Bob    7
Apples  10/6/2016 Bob    8
Apples  10/6/2016 Mike   9
Apples  10/7/2016 Steve 10
Apples  10/7/2016 Bob    1
Oranges 10/7/2016 Bob    2
Oranges 10/6/2016 Tom   15
Oranges 10/6/2016 Mike  57
Oranges 10/6/2016 Bob   65
Oranges 10/7/2016 Tony   1
Grapes  10/7/2016 Bob    1
Grapes  10/7/2016 Tom   87
Grapes  10/7/2016 Bob   22
Grapes  10/7/2016 Bob   12
Grapes  10/7/2016 Tony  15
  

Я хотел бы объединить это по Name , а затем по Fruit , чтобы получить общее количество Fruit на Name . Например:

 Bob,Apples,16
  

Я попробовал сгруппировать по Name и Fruit , но как мне получить общее количество Fruit ?

Комментарии:

1.вы можете использовать dfsql df.sql (‘ВЫБЕРИТЕ фрукты, сумму (число) СГРУППИРОВАТЬ По фруктам’) github.com/mindsdb/dfsql medium.com/riselab /…

Ответ №1:

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

 df.groupby(['Fruit','Name']).sum()

Out[31]: 
               Number
Fruit   Name         
Apples  Bob        16
        Mike        9
        Steve      10
Grapes  Bob        35
        Tom        87
        Tony       15
Oranges Bob        67
        Mike       57
        Tom        15
        Tony        1
  

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

Комментарии:

1. Вопрос в том, если данные считываются из Excel, а «Число» по умолчанию должно быть строкой при чтении данных из Excel, как использовать функцию sum()?

2. ##в ‘overview.csv’ есть пять столбцов данных temp = pd.read_csv(«обзор.csv») temp.groupby([временные столбцы[0],временные столбцы[1]])[временные столбцы[4]].sum() print(temp) не может получить сумму ‘временных столбцов [4]’

Ответ №2:

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

 df.groupby(['Name', 'Fruit'])['Number'].agg('sum')
  

Ответ №3:

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

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

Fruit   Name       Number
Apples  Bob        16
Apples  Mike        9
Apples  Steve      10
Grapes  Bob        35
Grapes  Tom        87
Grapes  Tony       15
Oranges Bob        67
Oranges Mike       57
Oranges Tom        15
Oranges Tony        1
  

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

 df.groupby(['Fruit','Name'])['Number'].sum()

               Number
Fruit   Name         
Apples  Bob        16
        Mike        9
        Steve      10
Grapes  Bob        35
        Tom        87
        Tony       15
Oranges Bob        67
        Mike       57
        Tom        15
        Tony        1
  

Ответ №4:

Оба других ответа достигают того, чего вы хотите.

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

 df.groupby(['Fruit','Name'],as_index = False).sum().pivot('Fruit','Name').fillna(0)



Name    Bob     Mike    Steve   Tom    Tony
Fruit                   
Apples  16.0    9.0     10.0    0.0     0.0
Grapes  35.0    0.0     0.0     87.0    15.0
Oranges 67.0    57.0    0.0     15.0    1.0
  

Ответ №5:

 df.groupby(['Fruit','Name'])['Number'].sum()
  

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

Ответ №6:

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

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

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

 df.groupby(['Name', 'Fruit']).agg({'Number': "sum"})
  

Ответ №7:

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

 df.set_index(['Fruit','Name']).sum(level=[0,1])
Out[175]: 
               Number
Fruit   Name         
Apples  Bob        16
        Mike        9
        Steve      10
Oranges Bob        67
        Tom        15
        Mike       57
        Tony        1
Grapes  Bob        35
        Tom        87
        Tony       15
  

Ответ №8:

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

 df['Number'] = df.groupby(['Fruit', 'Name'])['Number'].transform('sum')
df = df.drop_duplicates(subset=['Fruit', 'Name']).drop('Date', 1)
  

Затем вы можете удалить повторяющиеся строки в столбце Fruit и Name . Кроме того, вы можете удалить столбец, Date указав ось 1 ( 0 для строк и 1 для столбцов).

 # print(df)

      Fruit   Name  Number
0    Apples    Bob      16
2    Apples   Mike       9
3    Apples  Steve      10
5   Oranges    Bob      67
6   Oranges    Tom      15
7   Oranges   Mike      57
9   Oranges   Tony       1
10   Grapes    Bob      35
11   Grapes    Tom      87
14   Grapes   Tony      15

# You could achieve the same result with functions discussed by others: 
# print(df.groupby(['Fruit', 'Name'], as_index=False)['Number'].sum())
# print(df.groupby(['Fruit', 'Name'], as_index=False)['Number'].agg('sum'))
  

Существует официальное руководство Group by: split-apply-combine, в котором рассказывается о том, что вы можете сделать после group by.

Комментарии:

1. Привет, ребята, ваше решение действительно работает! моя версия python — 3.8, кажется, что это сработало, если мы использовали только sum().

2. @Rui не понимаю, вы только говорите, что это работает, так когда же это не работает?

3. Ynjxsjmh, я имею в виду, если я просто использую ‘df[‘Number’] = df.groupby([‘Fruit’, ‘Name’])[‘Number’].transform(‘sum’)’, я не могу получить сумму ‘Number’, сгруппированную по паре ‘Fruit’, ‘Name’. Но, если я добавлю строку, как предложено в вашем комментарии, df = df.drop_duplicates(subset= [‘Fruit’, ‘Name’])’, тогда я получу ожидаемую сумму.

Ответ №9:

Если вы хотите, чтобы у агрегированного столбца было пользовательское имя, такое как Total Number , Total и т.д. (все решения, приведенные здесь, приводят к созданию фрейма данных, в котором указан столбец aggregate Number ), используйте именованную агрегацию:

 df.groupby(['Fruit', 'Name'], as_index=False).agg(**{'Total Number': ('Number', 'sum')})
  

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

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

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

 SELECT Fruit, Name, sum(Number) AS Total
FROM df 
GROUP BY Fruit, Name
  

Говоря о SQL, есть pandasql модуль, который позволяет запрашивать фреймы данных pandas в локальной среде, используя синтаксис SQL. Это не часть Pandas, поэтому ее придется устанавливать отдельно.

 #! pip install pandasql
from pandasql import sqldf
sqldf("""
SELECT Fruit, Name, sum(Number) AS Total
FROM df 
GROUP BY Fruit, Name
""")
  

Ответ №10:

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

 df.sql('SELECT fruit, sum(number) GROUP BY fruit')
  

https://github.com/mindsdb/dfsql

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

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

Ответ №11:

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

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

или

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