开发者学堂课程【大数据 Spark 2020版(知识精讲与实战演练)第三阶段:有类型转换_as】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/690/detail/12068
有类型转换_as
有类型转换_as
前面,介绍过了 rdd. 如何转成一个 dataframe ,是通过 rdd.toDF->就转成了一个 Data Frame 对象,接下来,有一个问题,的问题是 Data frame 对象怎么转成一个 data set 类型的对象,要进行这种转换的话,那么其实 data frame 就是一个别名,叫做 type DataFrame = Dataset,但是,这个 Dataset 当中存放的是 Row 类型的数据,把这个 Row 转成一个具体的类型就可以了。
如何将 DataFrame =转化为 Dataset,大家在工作当中也会经常遇到这种操作,因为算子分为有类型和无类型的,大家也接触到了 map 算子对里面的对象来进行相应的转换和强类型转换操作,那么在这个 DataFrame 当中,想去调用 map 这种强类型的算子的话,得到的依旧是 Row 对象,还是不那么方便,所以需要进行这种转换。
接下来进入到 idea 当中见到的当中,先去创建出来一个方法,这个方法叫做 as。
这个案例相对来说比较重要的,这个操作也比较重要,所以就读取一个数据集,这个数据叫做 student tab10K,首先读的时候需要注意两点:
1、为其指定 SQL 信息,比如 ulysses thompson 这一列叫什么,它是什么类型的。
2、要去在中间指定 delimeter。
接下来,进行代码演示:
def as(): Unit = {
//1.读取
val schema = StructType (
Seq(
StructField(“name”,StringType),
StructField(“age”,StringType),
StructField(“gpa”,StringType),
)
)
val df DataFrame = spark.read//df 的类型为 DataFrame,通过 spark 的这个方法读出来的都是这个 read ,因为这个 read 获取到的对象叫做 DataFrame reader。
.schema(schema)
.option(“delimiter”,”\t”)//通过 option 去指定,然后指定 delimiter 是一个反斜杠 t,是一个制表符。
.csv( path =”dataset/studenttab10k”)//通过 CSV 去加载这个文件类型为 studenttab10k。
//2.转换
//本质上:Dataset[Row].as[student] => Dataset[student]
//Dataset[Row].as[student] => Dataset[student],把 Row 改为 person 是不行的,不能改为自己的类型。
假如改为 Dataset[String,int,float].as[student] => Dataset[student]
val ds: Dataset[student] = df .as[Student]
//3.输出
ds.show()
接下来,如果把 val df DataFrame = spark.read 这个地方改为 val df Dataset[Row] = spark.read,把 DataFrame 改为 Dataset 前面说过,DataFrame 是 Dataset 的一个别名,但是 Dataset 里面存放的是 Row 类型的对象,改成这种形式不会出现报错。
接下来进行相应的转换,要通过这个 df 的一个方法算子叫做 as,然后在后面给出了一个 student,比如说想把它转成一个 student 对象,应该先把 student 这个类创建出来:
case class_Student(name: String,_age:_Int,_gpa:Float)
那么这个时候 case class 创建出来,这时候就得到了 df,可以很轻易的看到,这个 ds 已经变成了 student 对象,也就是说,这个一般情况下,我们可以把一个元组,Row 这种对象类型的数据直接通过 ds 转成另外一个数据类型。
运行这代码:
这个代码是没问题的,已经转化为 Dataset 了。
总结:
本质上:Dataset[Row].as[student] => Dataset[student]
Dataset[Row].as[student] => Dataset[student],把 Row 改为 person 是不行的,不能改为自己的类型。
假如改为:
Dataset[String,int,float].as[student] => Dataset[student]
这就可以。那么 as 方法,其实是调用这个 Dataset 本身内部的一个转换器来进行每一条数据转换的。
这个操作其实理论上是比较重的,但是,它可以支持一些常见类型的一些转换,比如说 Row 对象类型,那再比如说元祖类型,那你自己的类行不行,就是必须得是常见的类型,这就是有类型转换_as。
