专栏首页月小水长数据分析利器 pandas 系列教程(四):对比 sql 学 pandas

数据分析利器 pandas 系列教程(四):对比 sql 学 pandas

作为 pandas 教程的第四篇,本篇将对比 sql 语言,学习 pandas 中各种类 sql 操作,文章篇幅较长,可以先收藏后食用,但不可以收藏后积灰~

为了方便,依然以下面这个 DataFrame 为例,其变量名为 df,设有一同样结构的 SQL 表,表名为 tb:

and、or、not 和集合资格测试 in

1、and

需求:选择成绩大于 90 分的男生的成绩单

sql 写法:select * from tb where sex="male" and grade>90

pandas 写法:and 符号 &df[(df['sex']=='male') & (df['grade']>90)]

常见的 pandas 错误写法:

  1. 由于 sql 的思维惯性,把 & 写成 and。
  2. & 两侧没加括号,写成df[df['sex']=='male' & df['grade']>90],这时会报错:TypeError: cannot compare a dtyped [int64] array with a scalar of type [bool],从字面意思来看是 int64 数组和布尔值无法比较,真正的原因是因为 ==、> 运算符的优先级并不比 & 高,从左往右看,第一个运算 df['sex']=='male'的结果就是一个布尔值,然后这个布尔值再与 df['grade'] 作 & 运算,这样就报错了。解决办法就是像正确写法那样,& 两侧加括号。

这样选择出来的 dataframe,其 index 是不连续的,因为 pandas 的选择,连同原来的 index 一起选择了,符合条件的行,在原来的 dataframe 中,index 几乎不可能连续(除开巧合)。所以必须 reset_index 下,这个函数有两个值得注意的参数 inplace drop,inplace 在 强大的 DataFrame 就讲过,如果原地修改就设置为 True;至于这个 drop ,设置为 False 则 index 列会被还原为普通列,否则的话就直接丢失,这里我们设置为 True,直接丢掉,否则的话,就会出现以只带文件名方式读取了保存 index 的 csv 文件那样的错误:出现一列 "unnamed: 0"。

and_df = df[(df['sex']=='male') & (df['grade']>90)]
and_df.reset_index(inplace=True, drop=True)
2、or

需求:选择分数大于 95 或者小于 85 的学生的成绩单

sql 写法:select * from tb where grade>95 or grade<85

pandas 写法:or 符号 |,即df[(df['grade']>95) | (df['grade']<85)]

3、not

需求:选择分数大于等于 85 并且小于等于 95 分的学生

分析:这个需求有很多写法,可以用 and, 也可以利用求补思想,即 not

sql 写法:select * frim tb where grade not in(select grade from tb where grade>85 and grade<95)

pandas 写法:not 符号 -,即 df[-((df['grade']>95) | (df['grade']<85))]

4、集合资格测试 in

需求:选择分数为 89、95 之一的学生

sql 写法:select * from tb where grade in (89, 95)

pandas 写法:df[df['grade'].isin([89, 95])]

上述的四个例子,都是整行查询,如果只需要查询某个字段,比如查询男生中语文成绩最差的学生的名字,以通过 loc 表达式实现,如下:

math_best_student = df.loc[(df['course']=='chinese')&(df['sex']=='male'), ['name','grade']].sort_values('grade').reset_index(drop=True).iloc[0, 0]

这行代码语法糖较多,分三步拆解:

  1. 条件选择:所有男生的语文成绩的姓名、(语文)成绩两个字段
  2. 成绩升序:按照成绩升序排列,注意 reset_index 重置索引,不需要 inplace,否则没有返回值,无法再黏语法糖。
  3. 切片选择:第 0 个学生,即成绩最差的学生的第 0 列 ,即 name 列。

groupby

groupby 即分组聚合,df.group_by() 即可实现,它返回的是一个 GroupBy 对象而不是 dataframe 需要对这个 GroupBy 对象进行后续的聚合函数调用才会返回 dataframe。

需求:数学、语文、英语三门课各自的平均分,最高分、最低分

sql 写法:select avg(grade),max(grade),min(grade) from tb group by course

pandas 写法:

gb_df = df.groupby('course').agg({
    'grade': ['mean', 'max', 'min']
})

其打印结果如下:

连接

sql 中有四种连接:内连接,左外连接,右外连接,全外连接, 以 df 为左表,right_df 为右表,在 name 字段连接为例。

df = pd.DataFrame({'name':['Bob','Alice','Joe']*3,
                   'sex':['male','female','male']*3,
                   'course': ['math', 'english', 'chinese', 'chinese', 'chinese', 'english', 'english', 'math', 'math'],
                   'grade':[99,92,89,88,95,93,95,79,89]})
right_df = pd.DataFrame({
    'name': ['Bob', 'Alice', 'Miller'],
    'number': [1001, 1002, 1003]
})

连接

解释

内连接

在 name 列上取交集,只保留左右两表都出现的 name,即只有 Bob、Alice 两人的共六门成绩

左外连接

保留左表中 name 中出现的而右表没有出现的,同时对应右表的 number 字段置空

右外连接

参见左外连接

全外连接

都置空

pandas 有 merge join 两个函数可以实现连接,区别如下:

  • merge 默认在左右两表中相同列合并,也可以 on, left_on, right_on 指定(左/右)列名
  • join 默认在 index 列合并,也可以 on 指定,没有 left_on、right_on

可以看到 merge 使用范围更广一点。

这四种连接对应的 sql 及 pandas 写法如下表:

连接

sql

pandas

内连接

select * from tb inner join right_tb on tb.name=right_tb.name

df.merge(right_df, how='inner') df.merge(right_df, on='name', how='inner')df.merge(right_df, left_on='name', right_on='name', how='inner')

左外连接

select * from tb left join right_tb on tb.name=right_tb.name

df.merge(right_df, how='left')

右外连接

select * from tb right join right_tb on tb.name=right_tb.name

df.merge(right_df, how='right')

全外连接

select * from tb full outer join right_tb on tb.name=right_tb.name

df.merge(right_df, how='outer')

本文分享自微信公众号 - 月小水长(inspurer),作者:BuyiXiao

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-06-26

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 数据分析利器 pandas 系列教程(二):强大的 DataFrame

    dataframe 是表格型的数据结构,由一组有序的列组成,可以看成是由 Series 组成的字典,举个例子:

    月小水长
  • Python 数据可视化实战:使用 PyQt5 和 Echarts 打造股票数据看板

    数据可视化大致可分为两类,一类是 excel、powerBI 这类不需要写代码的,另一类是需要写代码的;而对于 Python 来说,数据可视化框架,我个人觉得大...

    月小水长
  • wxPython+opencv 打造自己的画图板

    参数三: filetypes,比如我上面的设置过滤掉了其他非.jpg、.png文件

    月小水长
  • others

    http协议是无状态的通信协议,不会维持,每次请求后就会关闭,多以需要我们来维护用户的登录状态。维护用户的登录状态(或者说标识用户的身份信息或记录会话信息)有三...

    yawn
  • Jenkins指定具体分支持续集成-使用Generic Webhook Trigger插件和码云

    使用Generic Webhook Trigger插件实现Jenkins+WebHooks(码云)持续集成

    Java后端技术
  • 点餐系统的部署,Java点餐系统部署到腾讯云Linux服务器

    这里以腾讯云为例,我们首先要登录自己的腾讯云服务器,然后进入ssl证书申请页。

    编程小石头
  • [Glide4源码解析系列] — 3.Glide数据解码与转码

    继上一篇文章[Glide4源码解析系列]--2.Glide数据模型转换与数据抓取之后,已经过去几个月的时间,期间由于学习其他东西和项目的原因(其实是懒癌发作~)...

    开发的猫
  • electron菜单的基本使用

    对electron了解之后,让我们学习创建一个窗口,使用自己的编写的窗口 搭建环境可以看https://www.cnblogs.com/zhoulifeng/p...

    小周sri的码农
  • 孩子四岁了,还不会写红黑树怎么办?

    这孩子也太不让人省心了,为了帮助同事我们准备写篇入门文档。翻出算法导论。嗯!还好功底保持的不错,看完还是一如既往的:

    用户5521279
  • 雷军把小米发布会开到华为门口,发布了安卓版iPhone X

    量子位

扫码关注云+社区

领取腾讯云代金券