我如何熊猫组通过得到总和?

我正在使用这个数据框架:

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得到每个NameFruit的总数。例如:

Bob,Apples,16

我尝试通过NameFruit分组,但我如何得到Fruit的总数?

789759 次浏览

使用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()

其他两个答案都达到了你想要的效果。

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

你也可以使用agg函数,

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

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

如果你想保留原来的列FruitName,使用reset_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

你可以将groupby列设置为index,然后使用sumlevel

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

.agg()函数的变体;提供了(1)持久化类型DataFrame的能力,(2)应用平均值,计数,总和等,(3)在保持易读性的同时,在多个列上启用分组。

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

运用你的价值观……

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

你也可以在组by之后的列Number上使用变换()。此操作将使用sum函数计算一个组中的总数,结果是一个与原始数据帧具有相同索引的系列。

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

然后,可以删除列FruitName上的重复行。此外,你可以通过指定轴1来删除列Date (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'))

有一个官方教程分组方式:split-apply-combine讨论了在group by之后可以做什么。

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

如果你想要聚合的列有一个自定义的名字,比如Total NumberTotal等(这里所有的解决方案的结果是一个数据帧,其中聚合列命名为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模块允许你使用SQL语法在本地环境中查询pandas dataframe。它不是Pandas的一部分,所以必须单独安装。

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