spark的结构化API

1.结构化API概述

Apache Spark是一个用于大规模数据处理的快速,可靠,容错的分布式计算框架。
Spark有两套基本的API(Application Programming Interface,应用程序编程接口):

  1. 低级的“非结构化”API:弹性分布式数据集(RDD)
  2. 高级的“结构化”API:类型安全的结构化数据API——Dataset

结构化API是处理各种数据类型的工具,可处理非结构化的日志文件,半结构化的CSV文件,以及高度结构化的Parquet文件。结构化API指以下三种核心分布集合类型的API:
3. Dataset类型
4. DataFrame类型
5. SQL表和视图

结构化API适用于批处理和流处理。结构化API是在编写大部分数据处理程序时会用到的基础抽象。

Spark中的DataFrame和Dataset代表不可变的数据集合,可以通过它指定对特定位置数据的操作,该操作将以惰性评估方式执行。

1.1 Schema

Schema定义了DataFrame的列名和类型,可以手动定义或者从数据源读取模式。

1.2 结构化API执行概述

  1. 编写DataFrame/Dataset/SQL代码
  2. 如果代码能有效执行,Spark将其转换为一个逻辑执行计划(Logical Plan)。
  3. Spark将此逻辑执行计划转化为一个物理执行计划(Physical Plan),检查可行的优化策略,并在此过程中检查优化。
  4. spark在集群上执行该物理执行计划(RDD操作)

编写的代码通过控制台提交给Spark,或者以一个Spark作业的形式提交。然后代码将交由Catalyst优化器决定如何操作,并制定一个执行计划。最后代码被运行,得到的结果返回给用户。

在这里插入图片描述
逻辑计划

执行的第一阶段旨在获取用户代码并将其转换为逻辑计划。
在这里插入图片描述
逻辑计划仅代表一组抽象转换,并不涉及执行器或驱动器,他只是将用户的表达式集合转换为最优的版本。

物理计划
在成功创建优化的逻辑计划后,Spark开始执行物理计划流程。物理计划(通常称为Spark计划)通过生成不同的物理执行操作,并通过代价模型进行比较分析,从而确定如何在集群上执行逻辑计划。
在这里插入图片描述
执行
在选择一个物理计划时,Spark将所有代码运行在Spark的底层编程接口RDD上。Spark在运行时执行进一步优化,生成可以在执行期间优化任务或阶段的本地Java字节码,最终将结果返回给用户。

原文链接:https://blog.csdn.net/qq_38762390/article/details/115677514

2. 结构化API的基本操作

DataFrame的操作:聚合操作(aggregation),窗口函数(window function),连接操作(join)。
DataFrame由记录(record)组成,record是Row类型(与数据库表中的行相似)。一条record由多列组成。
模式定义了DataFrame列的名以及列的数据类型。DataFrame的分区定义了DataFrame以及Dataset在集群上的物理分布,而划分模式定义了partition的分配方式。

2.1 模式

模式定义了DataFrame列的名以及列的数据类型:

  1. 由数据源来定义模式(读时模式,schema-on-read)
  2. 自己显示定义

2.2 列和表达式

//引用列
df.col("columnName")
//列作为表达式
expr("someCol") == col("someCol")
expr("someCol"-5) == col("someCol")-5 == expr("someCol") - 5
//访问DataFrame的列
df.columns

表达式是一个DataFrame的列的函数,列就是表达式。

2.3 DataFrame转换操作

在处理DataFrame对象时,通常有以下几个目标:

  1. 添加行或列
  2. 删除行或列
  3. 将一行转换操作为一列(或反之)
  4. 根据列中的值更改行的顺序

三个工具:(借助这三个工具,可以解决处理DataFrame时遇到的大多数问题)

  1. 处理列或表达式时的select方法
  2. 处理字符串表达式时的selectExpr方法
  3. 有一些操作不针对列,此时org.apache.spark.sql.functions包中包含一组函数方法来提供额外支持。
df.select("col1", "col2").show() //选取两列,并查看
df.select(expr("colName AS recolName")).show() //选取列并改名
df.select(expr("colName AS recolName")).alias("colName") //列名又改为初始的名字
//select后跟expr操作非常常见,此操作可用selectExpr代替
df.selectExpr("colName AS recolName", "colName") //selectExpr创建复杂表达式构建DataFrame
//添加列
df.withColumn("name", lit(1)).show() //添加一列全为1的列
df.withColumn("withCountry", expr("col1 == col2"))//添加一个布尔表达式
//重命名列
df.withColumnRenamed("name", "re_name")
//删除列
df.drop()
//更改列类型(强制类型转换)
df.withColumn("count2", col("count").cast("long"))
//过滤行
df.filter(col("count") < 2)
df.filter("count < 2")
//获得去重后的行,distinct方法
df.select("col1", "col2").distinct().show()
//随机抽样
df.sample(withReplacement, fraction, seed).count()
//随机分割
df.randomSplit(Array(0.25,0.75))
//联合操作,必须保证两个DataFrame具有相同的模式和列数
df.union(newDF)
//行排序
df.sort("count")
//limit方法取记录
df.limit(5) //取前5条记录,行

//重划分和合并
df.rdd.getNumPartitions
df.repartition()

3.处理不同的数据类型

3.1 转换成spark类型:lit()

df.select(lit(5), lit(“five”), lit(5.0))

3.2 处理日期和时间戳类型

程序语言和数据库领域中,处理日期和时间一直都是难题。需要已知跟踪时区,和确保其格式正确可用。spark通过date和timestamp来处理相关问题。

date:日历日期
timestamp:日期和时间信息

    //将某一列字符串类型转换为时间戳类型
    val dateFrame = "dd/MM/yyyy HH:mm:ss"
    val timeStructruedLogon = logon.withColumn("date",to_timestamp(col("date"),dateFrame))
    timeStructruedLogon.printSchema()
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值