这是一个关于 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 列
点评:
- 简单的筛选逻辑可以使用此方式,复杂的逻辑不适合
- 这种方式有个特点,逻辑是以字符串形式存在,意味着,如果你希望用户能够在界面上填写筛选逻辑,此方法非常好用
基本的筛选方式就这么多,但是为了让他们多了解一些小技巧,接下来会介绍一些比较曲折的方式
方式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 会出现警告信息,提醒你,"可能你的筛选出问题"
推荐阅读:
- sql题目pandas解法(01):筛选、all、any常用技巧
- 懂Excel轻松入门Python数据分析包pandas(29):轻松做出筛选控件