我熊猫如何分组以获得总和?

How do I Pandas group-by to get sum?

提问人:Trying_hard 提问时间:10/8/2016 最后编辑:blackravenTrying_hard 更新时间:3/16/2023 访问量:867125

问:

我正在使用这个数据框:

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

我想将其聚合起来,然后通过得到每个 .例如:NameFruitFruitName

Bob,Apples,16

我尝试按 和 分组,但我如何获得 的总数?NameFruitFruit

Python Pandas DataFrame 分组聚合

评论

2赞 Jorge Torres 4/20/2021
你可以使用 dfsql df.sql('SELECT fruit, sum(number) GROUP BY fruit') github.com/mindsdb/dfsql medium.com/riselab/...

答:

440赞 Steven G 10/8/2016 #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()

评论

0赞 Rui 11/22/2022
问题是,如果数据是从excel中读取的,当我们从excel中读取数据时,“Number”默认应该是一个字符串,如何使用sum()功能?
0赞 Rui 11/22/2022
##there 是 'overview.csv 中的五列数据 temp = pd.read_csv(“overview.csv”) temp.groupby([temp.columns[0],temp.columns[1]])[temp.columns[4]].sum() print(temp) 无法获取 'temp.columns[4] 的总和
62赞 Demetri Pananos 10/8/2016 #2

其他两个答案都实现了你想要的。

您可以使用该功能将数据排列在一个漂亮的表格中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
265赞 Saurabh 10/8/2016 #3

您也可以使用 agg 函数,

df.groupby(['Name', 'Fruit'])['Number'].agg('sum')
35赞 jared 3/11/2018 #4
df.groupby(['Fruit','Name'])['Number'].sum()

您可以选择不同的列来对数字求和。

207赞 Gazala Muhamed 7/2/2018 #5

如果要保留原始列 和 ,请使用 。否则,将成为索引的一部分。FruitNamereset_index()FruitName

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
12赞 BENY 11/21/2018 #6

您可以将该列设置为然后使用groupbyindexsumlevel

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
24赞 xxyjoel 2/2/2020 #7

.agg() 函数的变体;提供以下功能:(1) 持久化类型 DataFrame,(2) 应用平均值、计数、求和等,以及 (3) 在保持易读性的同时在多个列上启用 Groupby。

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

使用您的价值观...

df.groupby(['Name', 'Fruit']).agg({'Number': "sum"})
11赞 Ynjxsjmh 3/18/2021 #8

您也可以在分组依据之后的列上使用 transform()。此操作将使用 function 计算一组中的总数,结果是一个与原始 DataFrame 具有相同索引的序列。Numbersum

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

然后,您可以将重复的行放在列和 上。此外,您可以通过指定轴(对于行和列)来删除列。FruitNameDate101

# 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 讨论分组后可以做什么。

评论

0赞 Rui 11/22/2022
嗨,大家好,您的解决方案确实有效!我的 Python 版本是 3.8,如果我们只使用 sum(),它似乎确实有效。
0赞 Ynjxsjmh 11/23/2022
@Rui 不明白,你只说它有效,那么什么时候不起作用?
0赞 Rui 11/23/2022
Ynjxsjmh,我的意思是,如果我只使用 'df['Number'] = df.groupby(['Fruit', 'Name'])['Number'].transform('sum')',我无法获得按 'Fruit'、'Name' 对分组的 'Number' 的总和。但是,如果我按照您的评论建议添加该行,df = df.drop_duplicates(subset=['Fruit', 'Name'])',那么我就得到了预期的总和。
2赞 Jorge Torres 4/20/2021 #9

你可以使用 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

3赞 cottontail 7/8/2022 #10

如果希望聚合列具有自定义名称,例如 等(此处的所有解决方案都会生成一个以聚合列命名的 DataFrame),请使用命名聚合:Total NumberTotalNumber

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,有一个模块允许你使用SQL语法在本地环境中查询pandas数据帧。它不是 Pandas 的一部分,因此必须单独安装。pandasql

#! pip install pandasql
from pandasql import sqldf
sqldf("""
SELECT Fruit, Name, sum(Number) AS Total
FROM df 
GROUP BY Fruit, Name
""")
1赞 Abdul Moiz 12/16/2022 #11

您可以使用 reset_index() 重置总和后的索引

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

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