python中agg求比率_python处理数据的风骚操作[pandas 之 groupby&agg]

介绍

每隔一段时间我都会去学习、回顾一下python中的新函数、新操作。这对于你后面的工作是有一定好处的。

本文重点介绍了pandas中groupby、Grouper和agg函数的使用。这2个函数作用类似,都是对数据集中的一类属性进行聚合操作,比如统计一个用户在每个月内的全部花销,统计某个属性的最大、最小、累和、平均等数值。

其中,agg是pandas 0.20新引入的功能

groupby && Grouper

首先,我们从网上把数据下载下来,后面的操作都是基于这份数据的:

import pandas as pd

df = pd.read_excel("https://github.com/chris1610/pbpython/blob/master/data/sample-salesv3.xlsx?raw=True")

df["date"] = pd.to_datetime(df['date'])

df.head()

(图片来自于jupyter notebook,强烈推荐使用它作为python的交互工具)

下面,我们统计'ext price'这个属性在每个月的累和(sum)值,resample 只有在index为date类型的时候才能用:

df.set_index('date').resample('M')['ext price'].sum()

date

2014-01-31 185361.66

2014-02-28 146211.62

2014-03-31 203921.38

2014-04-30 174574.11

2014-05-31 165418.55

2014-06-30 174089.33

2014-07-31 191662.11

2014-08-31 153778.59

2014-09-30 168443.17

2014-10-31 171495.32

2014-11-30 119961.22

2014-12-31 163867.26

Freq: M, Name: ext price, dtype: float64

进一步的,我们想知道每个用户每个月的sum值,那么就需要一个groupby了:

df.set_index('date').groupby('name')['ext price'].resample("M").sum()

name date

Barton LLC 2014-01-31 6177.57

2014-02-28 12218.03

2014-03-31 3513.53

2014-04-30 11474.20

2014-05-31 10220.17

2014-06-30 10463.73

2014-07-31 6750.48

2014-08-31 17541.46

2014-09-30 14053.61

2014-10-31 9351.68

2014-11-30 4901.14

2014-12-31 2772.90

Cronin, Oberbrunner and Spencer 2014-01-31 1141.75

2014-02-28 13976.26

2014-03-31 11691.62

2014-04-30 3685.44

2014-05-31 6760.11

2014-06-30 5379.67

2014-07-31 6020.30

2014-08-31 5399.58

2014-09-30 12693.74

2014-10-31 9324.37

2014-11-30 6021.11

2014-12-31 7640.60

Frami, Hills and Schmidt 2014-01-31 5112.34

2014-02-28 4124.53

2014-03-31 10397.44

2014-04-30 5036.18

2014-05-31 4097.87

2014-06-30 13192.19

...

Trantow-Barrows 2014-07-31 11987.34

2014-08-31 17251.65

2014-09-30 6992.48

2014-10-31 10064.27

2014-11-30 6550.10

2014-12-31 10124.23

White-Trantow 2014-01-31 13703.77

2014-02-28 11783.98

2014-03-31 8583.05

2014-04-30 19009.20

2014-05-31 5877.29

2014-06-30 14791.32

2014-07-31 10242.62

2014-08-31 12287.21

2014-09-30 5315.16

2014-10-31 19896.85

2014-11-30 9544.61

2014-12-31 4806.93

Will LLC 2014-01-31 20953.87

2014-02-28 13613.06

2014-03-31 9838.93

2014-04-30 6094.94

2014-05-31 11856.95

2014-06-30 2419.52

2014-07-31 11017.54

2014-08-31 1439.82

2014-09-30 4345.99

2014-10-31 7085.33

2014-11-30 3210.44

2014-12-31 12561.21

Name: ext price, Length: 240, dtype: float64

结果肯定是对的,但是不够完美。我们可以使用Grouper写得更加简洁:

# df.set_index('date').groupby('name')['ext price'].resample("M").sum()

df.groupby(['name', pd.Grouper(key='date', freq='M')])['ext price'].sum()

结果和上面?一样,就不列出来了。

显然,这种写法多敲了很多次键盘,那么它的好处是啥呢?

首先,逻辑上更加直接,当你敲代码完成以上统计的时候,你首先想到的就是groupby操作,而set_index, resample好像不会立马想到。想到了groupby这个'动作'之后,你就会紧接着想按照哪个key来操作,此时

你只需要用字符串,或者Grouper把key定义好就行了。最后使用聚合函数,就得到了结果。所以,从人类的

思考角度看,后者更容易记忆。

另外,Grouper里的freq可以方便的改成其他周期参数(resample也可以),比如:

# 按照年度,且截止到12月最后一天统计ext price的sum值

df.groupby(['name', pd.Grouper(key='date', freq='A-DEC')])['ext price'].sum()

name date

Barton LLC 2014-12-31 109438.50

Cronin, Oberbrunner and Spencer 2014-12-31 89734.55

Frami, Hills and Schmidt 2014-12-31 103569.59

Fritsch, Russel and Anderson 2014-12-31 112214.71

Halvorson, Crona and Champlin 2014-12-31 70004.36

Herman LLC 2014-12-31 82865.00

Jerde-Hilpert 2014-12-31 112591.43

Kassulke, Ondricka and Metz 2014-12-31 86451.07

Keeling LLC 2014-12-31 100934.30

Kiehn-Spinka 2014-12-31 99608.77

Koepp Ltd 2014-12-31 103660.54

Kuhn-Gusikowski 2014-12-31 91094.28

Kulas Inc 2014-12-31 137351.96

Pollich LLC 2014-12-31 87347.18

Purdy-Kunde 2014-12-31 77898.21

Sanford and Sons 2014-12-31 98822.98

Stokes LLC 2014-12-31 91535.92

Trantow-Barrows 2014-12-31 123381.38

White-Trantow 2014-12-31 135841.99

Will LLC 2014-12-31 104437.60

Name: ext price, dtype: float64

agg

从0.20.1开始,pandas引入了agg函数,它提供基于列的聚合操作。而groupby可以看做是基于行,或者说index的聚合操作。

从实现上看,groupby返回的是一个DataFrameGroupBy结构,这个结构必须调用聚合函数(如sum)之后,才会得到结构为Series的数据结果。

而agg是DataFrame的直接方法,返回的也是一个DataFrame。当然,很多功能用sum、mean等等也可以实现。但是agg更加简洁, 而且传给它的函数可以是字符串,也可以自定义,参数是column对应的子DataFrame

举个栗子?吧:

df[["ext price", "quantity", "unit price"]].agg(['sum', 'mean'])

怎么样,是不是比使用

df[["ext price", "quantity"]].sum()

df['unit price'].mean()

简洁多了?

上例中,你还可以针对不同的列使用不同的聚合函数:

df.agg({'ext price': ['sum', 'mean'], 'quantity': ['sum', 'mean'], 'unit price': ['mean']})

另外,自定义函数怎么用呢,也是so easy.

比如,我想统计sku中,购买次数最多的产品编号,可以这样做:

# 这里的x是sku对应的column

get_max = lambda x: x.value_counts(dropna=False).index[0]

df.agg({'ext price': ['sum', 'mean'],

'quantity': ['sum', 'mean'],

'unit price': ['mean'],

'sku': [get_max]})

看起来很不协调,把它去掉:

get_max = lambda x: x.value_counts(dropna=False).index[0]

# python就是灵活啊。

get_max.__name__ = "most frequent"

df.agg({'ext price': ['sum', 'mean'],

'quantity': ['sum', 'mean'],

'unit price': ['mean'],

'sku': [get_max]})

另外,还有一个小问题,那就是如果你希望输出的列按照某个顺序排列,可以使用collections的OrderedDict:

get_max = lambda x: x.value_counts(dropna=False).index[0]

get_max.__name__ = "most frequent"

import collections

agg_dict = {

'ext price': ['sum', 'mean'],

'quantity': ['sum', 'mean'],

'unit price': ['mean'],

'sku': [get_max]}

# 按照列名的长度排序。 OrderedDict的顺序是跟插入顺序一致的

df.agg(collections.OrderedDict(sorted(agg_dict.items(), key = lambda x: len(x[0]))))

总结

好好学习,天天向上!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,关于Pandas的groupby和agg操作,我可以为您进行介绍和讲解,以下是详细内容: 在Pandas,groupby和agg是非常常用的两个操作,可以对数据集进行分组聚合操作,非常适用于数据分析和处理。下面我会分别进行介绍。 首先,我们来看看groupby操作。groupby可以将数据集按照某一列或多列进行分组,然后对每个组进行操作。例如: ```python import pandas as pd data = pd.DataFrame({'name': ['Alice', 'Bob', 'Charlie', 'David', 'Eva', 'Frank', 'Grace', 'Hank', 'Ivy', 'Jack'], 'gender': ['F', 'M', 'M', 'M', 'F', 'M', 'F', 'M', 'F', 'M'], 'age': [21, 23, 25, 27, 29, 31, 33, 35, 37, 39], 'score': [80, 85, 90, 95, 96, 97, 98, 99, 100, 100]}) grouped = data.groupby('gender') ``` 以上代码,我们用了一个DataFrame来存储一些人的信息,包括姓名、性别、年龄和分数。我们使用了groupby将数据按照性别进行分组,将得到一个groupby对象。接下来,我们可以对每个组进行操作,例如: ```python print(grouped.mean()) ``` 运行以上代码,输出结果为: ``` age score gender F 29.333333 92.0 M 32.800000 93.4 ``` 以上代码,我们使用了mean函数对每个组进行操作出了每个组的平均年龄和平均分数。可以看到,我们得到了按照性别分组后的结果。 接下来,我们来看看agg操作agg可以对每个组进行多个操作,例如最大值、最小值、平均值等等。例如: ```python print(grouped.agg({'age': 'mean', 'score': ['min', 'max']})) ``` 运行以上代码,输出结果为: ``` age score mean min max gender F 29.333333 80 98 M 32.800000 85 100 ``` 以上代码,我们使用了agg函数对每个组进行操作出了每个组的平均年龄和分数的最大值和最小值。可以看到,我们得到了按照性别分组后的结果。 总的来说,groupby和agg是非常常用的Pandas操作,能够帮助我们方便地对数据集进行分组聚合操作

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值