这是一个关于 pandas 从基础到进阶的练习题系列,来源于 github 上的 guipsamora/pandas_exercises 。这个项目从基础到进阶,可以检验你有多么了解 pandas。
我会挑选一些题目,并且提供比原题库更多的解决方法以及更详尽的解析。
计划每天更新一期,希望各位小伙伴先自行思考,再查看答案。如果对你有帮助,记得转发推荐给你的好友!
上期文章:pandas每天一题-题目8:去重计数的多种实现方式
后台回复"数据",可以下载本题数据集
如下数据:
数据描述:
需求:计算订单平均收入?
说明:
假如有10笔订单,总收入(quantity * item_price)是200,那么订单平均收入 = 200/10=20
虽然需求很简单,但有些实现方式考验你的 groupby 理解程度!
下面是答案了
初学者容易给出的错误答案是:
df = pd.read_csv('chipotle.tsv',sep='\t',converters={'item_price': lambda x: float(x[1:-1])})
df.eval('quantity * item_price').mean()
问题在于数据颗粒度不是一个订单,而是一个订单中的明细项。
因此第一种方式就是调整颗粒度:
(
df.groupby('order_id')
.apply(
lambda g: g.eval('quantity * item_price').sum()
)
.mean()
)
21.394231188658654
使用 groupby+ apply 比较慢,我们可以把计算收入放在分组之前:
(
df.eval('revenue=quantity * item_price')
.groupby('order_id')
.agg({'revenue':sum})['revenue']
.mean()
)
有没有发现,收入只是一个临时变量,但代码中却多次出现(revenue)。可否省略?这引出方式2
pandas允许直接对列(Series)做分组:
(
df.eval('quantity * item_price')
.groupby(df.order_id)
.sum()
.mean()
)
点评:
推荐阅读: