![e5cee4c1b627cef2059337d4e8370129.png](https://i-blog.csdnimg.cn/blog_migrate/c0556411c095179d75ba6e3d756d75e2.jpeg)
此系列文章收录在公众号中:数据大宇宙 > 数据处理 >E-pd
转发本文并私信我"python",即可获得Python资料以及更多系列文章(持续更新的)
经常听别人说 Python 在数据领域有多厉害,结果学了很长时间,连数据处理都麻烦得要死。后来才发现,原来不是 Python 数据处理厉害,而是他有数据分析神器—— pandas
前言
Excel 中除了 Vlookup 函数,一系列条件统计函数(sumif、countif、maxif)就用得最多,毕竟在 Excel 中进行数据统计是常见需求。
今天我们来看看在 pandas 中如何做到条件统计。
本文使用泰坦尼克号沉船事件的乘客名单作为例子:
![911d6c88de0722f5b3282fc632e6ce56.png](https://i-blog.csdnimg.cn/blog_migrate/f402b4f820ab2fcccab27091b0ed47b6.jpeg)
- pclass:船舱等级
- survived:是否生还
- fare:票价
- sex:性别
- home.dest:住址
需求1:性别统计
"男女分别有多少人?"
这需要我们在 Excel 中有很多方式完成,比如透视表或函数公式,下面简单列出函数公式的做法:
![61b682c2f211e7dcfc688db13d2b6302.png](https://i-blog.csdnimg.cn/blog_migrate/3182f8af31c6d1b72fe26b712d2d6279.jpeg)
- 简单使用 countifs 即可
这里不再单独使用 countif 了,管他是否只有一个条件,统一用 xxxifs 类函数即可
在 pandas ,不会有啥条件统计函数的,因为这就是先筛选,再统计:
![e5059cd94c4fa6b65a20674d3fb3fa4e.png](https://i-blog.csdnimg.cn/blog_migrate/57cb6db6acbe2aa9a53e9dea6f00415f.jpeg)
- 行2:得到 性别 列是女性的 bool 列
- 行3:df[cond] 就是女性的记录,简单通过 len 方法,即可得到记录数(人数)
不过你可能会觉得这很麻烦,因为如果还要男性的人数,也需要执行一次差不多的代码。
实际上我们可以直接对 性别 列分组统计即可:
![4db3d251d138a0e34040801f1cf8ba19.png](https://i-blog.csdnimg.cn/blog_migrate/1783ccd056a98b6f33419bd4ddd88b7f.jpeg)
- 不多说了,代码语义简直与中文一样
- 这里唯一不好的地方是,需要通过 size 方法获得每个分组的记录数
![0ee50a5df7d310f4b9e839e5997f5c93.png](https://i-blog.csdnimg.cn/blog_migrate/099d228c881096d2fe59a462c23ee1f7.jpeg)
需求2:不同的统计方法
刚刚是求人数,现在希望求出女性的平均票价。
以下是 Excel 的公式做法:
![2c916a90ca77199f0674be49e11b1f93.png](https://i-blog.csdnimg.cn/blog_migrate/f76f65494ebf167db39a277bd47d45a2.jpeg)
那么 pandas 的做法呢?
想必聪明的你一定大概知道怎么做,pandas 中求平均的是方法 mean:
![0e6f5c3c8057186839fc6c45cd4d526b.png](https://i-blog.csdnimg.cn/blog_migrate/7f2e7037c02a8ffbc4bf1956f0140b36.jpeg)
- 行3:同样语义非常清晰。.fare.mean() 恰好反映"票价的平均"
同样,简单分组即可一次获得所有分组的统计信息:
![d4e65006de430750d35663a63181e460.png](https://i-blog.csdnimg.cn/blog_migrate/9bfdbe7ceea89fd1ec72283838392dcf.jpeg)
- 按 sex 分组,求 票价 的 平均
需求3:非常规匹配
上面的条件都是完全符合,有时候我们需要统计有包含关系的条件。
"住址是New York 的人数"
Excel 的 xxifs 类函数公式都能支持通配符:
![a398de01aefd00ff6842ffb721ddcb8c.png](https://i-blog.csdnimg.cn/blog_migrate/3728a7a571a918e3ebba2bbc19d739cc.jpeg)
- 前后用 * 包围内容,表示包含此内容即符合条件
在 pandas 中,由于筛选与统计是独立分开的,因此只需要知道怎么筛选,那么此需求即可迎刃而解:
![f2bbafb0b37e4a3e6fe2ee34ae5db3b3.png](https://i-blog.csdnimg.cn/blog_migrate/dfd6c9515a9c229821549e643b8d2144.jpeg)
- 行2:由于 住址 列是字符串类列,使用 .str 可访问字符串类型列的各种方法
- contains 判断列中是否包含指定内容。如果本身内容是 nan(不存在值) ,那么直接赋值为 False
如果我们只需要 住址 结尾是 NY 的人数?
Excel 中由于用通配符,因此表达更直接:
![aacb1656dc50bc49487c81f6f1e1ecea.png](https://i-blog.csdnimg.cn/blog_migrate/3c1decc16a3cbacc6d275581dd4ec4c8.jpeg)
- 注意,没有修改公式,只是输入内容变成 *NY ,表示 NY 前面可以是任意内容
在 pandas 这麻烦多了,这次不能使用 contains 方法:
![641bd9220d1d9317f0a6b7ec7d193496.png](https://i-blog.csdnimg.cn/blog_migrate/30c6670a4797a20084f2f820133e61a0.jpeg)
- 行2:使用 endswith 方法即可完成
怎么与 Excel 的统计结果不一样!!
你会发现,Excel 的统计结果包含小写字母的 ny 结尾!
![29acc48ff4a686b41ac27e10837ceda3.png](https://i-blog.csdnimg.cn/blog_migrate/90086ef61fbde4428eca2e7d359be04e.jpeg)
一次解决所有问题
以上 pandas 的做法主要有以下问题:
- 不能用通配符表达不同的文本规则,只能用不同的方法,我记不住这么多方法呀
- 不能忽略大小写(实际上面的需求,pandas 的结果更合理)
其实 .str.contains 方法本身就是使用正则表达式,我们可以直接用 contains 解决所有文本规则相关问题:
![8557c20341878d48bba24308b2f152cc.png](https://i-blog.csdnimg.cn/blog_migrate/7d406c86398f3635ea2bcad63528399f.jpeg)
- 行2: NY$ ,表示 NY 在结尾处
- 参数 case = False ,不区分大小写
pandas 用于文本匹配的还有 match 方法,此系列文章不再深入讲解了。更多高级应用方法,请关注 pandas 专栏 [带你玩转Python数据处理—pandas]