相关文章推荐
成熟的红薯  ·  Where I can find ...·  5 月前    · 
狂野的麦片  ·  Spring Cloud ...·  1 年前    · 
首发于 数据分析
SQL、Pandas和Spark:常用数据查询操作对比

SQL、Pandas和Spark:常用数据查询操作对比

导读:当今信息时代,数据堪称是最宝贵的资源。沿承 系列文章 ,本文对SQL、Pandas和Spark这3个常用的数据处理工具进行对比,主要围绕数据查询的主要操作展开。

本文首先介绍SQL查询操作的一般流程,对标SQL查询语句的各个关键字,重点针对Pandas和Spark进行介绍,主要包括10个常用算子操作。


01 SQL标准查询

谈到数据,必会提及数据库;而提及数据库,则一般指代关系型数据库(R DB),操作关系型数据库的语言则是SQL(Structured Query Language)。SQL本质上仍然属于一种编程语言,并且有着相当悠久的历史,不过其语法特性却几乎没怎么变更过,从某种意义上讲这也体现了SQL语言的过人之处。

在最新TIOBE排行榜中,SQL位居第10位

一般而言,一句标准的SQL语句按照书写顺序通常含有如下关键词:

  • select:指定查询字段
  • distinct:对查询结果字段进行去重
  • from:明确查询的数据库和表
  • join on:指定查询数据源自多表连接及条件
  • where:设置查询结果过滤条件
  • group by:设置分组聚合统计的字段
  • having:依据聚合统计后的字段进一步过滤
  • order by:设置返回结果排序依据
  • limit:限定返回结果条数

这是一条SQL查询语句中所能涉及的主要关键字,经过解析器和优化器之后,最后的执行过程则又与之差别很大,执行顺序如下:

  • from:首先找到待查询的表
  • join on:如果目标数据表不止一个,则对多表建立连接关系
  • where:根据查询条件过滤数据记录
  • group by:对过滤结果进行分组聚合
  • having:对分组聚合结果进行二次过滤
  • select:对二次过滤结果抽取目标字段
  • distinct:根据条件进行去重处理
  • order by:对去重结果进行排序
  • limit:仅返回排序后的指定条数记录
曾经,个人一度好奇为何不将SQL语句的书写顺序调整为与执行顺序一致,那样更易于理解其中的一些技术原理,但查询资料未果后,就放弃了……

当然,本文的目的不是介绍SQL查询的执行原理或者优化技巧,而仅仅是对标SQL查询的几个关键字,重点讲解在Pandas和Spark中的实现。


02 Pandas和Spark实现SQL对应操作

以下按照SQL执行顺序讲解SQL各关键字在Pandas和Spark中的实现,其中Pandas是Python中的数据分析工具包,而Spark作为集Java、Scala、Python和R四种语言的通用分布式计算框架,本文默认以Scala语言进行讲述。

1)from。由于Python和Scala均为面向对象设计语言,所以Pandas和Spark中无需from,执行 df.xxx 操作的过程本身就蕴含着from的含义。

2)join on。join on在SQL多表查询中是很重要的一类操作,常用的连接方式有inner join、left join、right join、outer join以及cross join五种,在Pandas和Spark中也都有相应关键字。

Pandas:Pandas实现join操作有两个主要的API:merge和join。其中merge是Pandas的顶层接口(即可直接调用pd.merge方法),也是DataFrame的API,支持丰富的参数设置,主要介绍如下:

def merge(
    left,  # 左表
    right,  # 右表
    how: str = "inner",  # 默认连接方式:inner
    on=None,  # SQL中on连接一段,要求左表和右表中 公共字段
    left_on=None,  # 设置左表连接字段
    right_on=None,  # 设置右表连接字段
    left_index: bool = False,  # 利用左表索引作为连接字段
    right_index: bool = False,  # 利用右表索引作为连接字段
    sort: bool = False,  # join结果排序
    suffixes=("_x", "_y"),  # 非连接字段有重名时,可s何止后缀
    copy: bool = True, 
    indicator: bool = False,
    validate=None,
) -> "DataFrame":

上述参数中,可以设置on连接条件的方式主要有3种:即若连接字段为两表共有字段,则可直接用on设置;否则可分别通过left_on和right_on设置;当一个表的连接字段是索引时,可设置left_index为True。

与merge操作类似,join可看做是merge的一个简化版本,默认以索引作为连接字段,且仅可通过DataFrame来调用,不是Pandas的顶级接口(即不存在pd.join方法)。

另外,concat也可通过设置axis=1参数实现横向两表的横向拼接,但更常用于纵向的union操作。

Spark:相较于Pandas中有多种实现两个DataFrame连接的方式,Spark中接口则要单一许多,仅有join一个关键字,但也实现了多种重载方法,主要有如下3种用法:

// 1、两个DataFrame有公共字段,且连接条件只有1个,直接传入连接列名
df1.join(df2, "col")
// 2、有多个字段,可通过Seq传入多个字段
df1.join(df2, Seq("col1", "col2")