pandas每天一题-题目4:原来查找top n记录也有这种方式

2021-09-01 14:21:03 浏览数 (2)

这是一个关于 pandas 从基础到进阶的练习题系列,来源于 github 上的 guipsamora/pandas_exercises 。这个项目从基础到进阶,可以检验你有多么了解 pandas。

我会挑选一些题目,并且提供比原题库更多的解决方法以及更详尽的解析

计划每天更新一期,希望各位小伙伴先自行思考,再查看答案。如果对你有帮助,记得转发推荐给你的好友!

上期文章:pandas每天一题-题目1、2、3

后台回复"数据",可以下载本题数据集

如下数据:

数据描述:

  • 此数据是订单明细表。一个订单会包含很多明细项,表中每个样本(每一行)表示一个明细项
  • order_id 列存在重复
  • quantity 是明细项数量

请找出数量最多的明细项(并列最多,全部列出),要求列出其所有信息(上表中的列)。

格式如下:

接下来就是答案了!


你可能一开始想到的答案是这样子:

代码语言:javascript复制
df.nlargest(1,'quantity',keep='all')

这是不对的。因为 item_name 相当于是一个产品名字,它可能同时存在于多个订单中。

上面的结果只能是"找出数据中,数量最多的行"

因此,我们应该这样做:

代码语言:javascript复制
(
    df.groupby(['item_name'])
    .agg({'quantity': sum,})
    .nlargest(1, 'quantity', keep='all')
)
  • 行2:按名字分组
  • 行3:汇总数量
  • 行4:取最多数量的。这里要说明一下,因为分组汇总后的结果仍然是一个 DataFrame(表格),因此可以继续使用他的各种方法
  • 为了做到需求中"并列最多,全部列出",这里设置的参数 keep

看看 nlargest 的参数描述:

关键知识点:

  1. 分组统计。df.groupby agg ,常用操作,必须掌握
  2. 取前n最大。df.nlargest

解法2

如果最多只有一笔,我们也可以使用:

代码语言:javascript复制
(
    df.groupby(['item_name'])
    .agg({'quantity': sum,})
    .sort_values( 'quantity', ascending=False)
    .head(1)
)
  • 行4:按数量倒序(ascending=False)排序
  • 行5:取第一行

那么,这种方式下,可以做到"并列最多,全部列出"的需求吗?

我们尝试一下。

首先,由于数据到了50才出现重复:

于是,我们把结果从50开始截取,当作是汇总后的结果:

代码语言:javascript复制
res = (
    df.groupby(['item_name'])
    .agg({'quantity': sum,})
    .sort_values( 'quantity', ascending=False)
    .query('quantity<=50')
)
res

其实道理很简单,求出最大值,把数量为最大值的行保留即可:

代码语言:javascript复制
res = (
    df.groupby(['item_name'])
    .agg({'quantity': sum,})
    .sort_values( 'quantity', ascending=False)
    .query('quantity<=50')
)

maxv = res.iloc[0,0]
res.query('quantity==@maxv')
  • 行8:取出汇总数据的第一行第一列。因为是倒序排序,这个值就是最大值
  • 行9:把等于最大值的行保留即可

这种方式比较繁琐,如果只是求n大记录,建议使用 nlargest

推荐阅读:

  1. python 方法太多了,怎么记住?在 JupyterNotebook中这几招很有用

0 人点赞