pandas每天一题-题目11:筛选数据也有3种方式,最后一种揭示本质

2021-09-01 14:22:20 浏览数 (2)

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

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

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

上期文章:pandas每天一题-题目10:去重计数的额外方式

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

如下数据:

数据描述:

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

需求:

列出数量只有1件的明细项

下面是答案了


方式1

pandas 最基本的操作——批量筛选:

代码语言:javascript复制
cond = df['quantity']==1
df[cond]
  • 行1:构造 bool 条件列
  • 行2:把条件列传入 df[条件列] 中,基于索引对齐原则,true 对应的行将被保留

点评:

这是最常用的筛选方式,建议所有初学者应该掌握


方式2

简单的筛选,有时候你不希望构造 bool 列,pandas 提供更加直观的方式:

代码语言:javascript复制
df.query('quantity==1')

本质上,query 方法内部的实现与方式1的一样。内部它使用 df.eval 得到 bool 列

点评:

  1. 简单的筛选逻辑可以使用此方式,复杂的逻辑不适合
  2. 这种方式有个特点,逻辑是以字符串形式存在,意味着,如果你希望用户能够在界面上填写筛选逻辑,此方法非常好用

基本的筛选方式就这么多,但是为了让他们多了解一些小技巧,接下来会介绍一些比较曲折的方式


方式3

本身在 pandas 中取出某些行,其实只有一种最快速的方式,就是通过行索引取出:

代码语言:javascript复制
idx = [0,1,2]
df.loc[idx]

那么,在方式1中,通过 bool 列得到 true 对应的行,其实道理是一样:

代码语言:javascript复制
cond = df['quantity'] == 1
idx = cond.values.nonzero()[0]
idx
  • 行2:Series.values 得到 numpy 的数组。其方法 nonzero 可以快速把非0去掉。
  • idx 得到的就是 true 对应的行索引

最后,也只不过是用得到的行索引取出行而已。

代码语言:javascript复制
df.loc[idx]

这就是所谓的索引对齐了。如果你传入一个行索引与 df 不一致的 bool 列,这就会导致筛选结果错位。

此时,pandas 会出现警告信息,提醒你,"可能你的筛选出问题"


推荐阅读:

  1. sql题目pandas解法(01):筛选、all、any常用技巧
  2. 懂Excel轻松入门Python数据分析包pandas(29):轻松做出筛选控件

0 人点赞