Spark笔记整理之RDD转化DataFrame

1.概述

RDD转化为DataFrame共有两种方式,下面我将结合源码,对这两种方式进行试验和讲解

  • 通过反射的方式,这种方式需要事先知道这份数据的Schema信息,才能使用,应用场景例如:读取HDFS数据等等

  • 通过编码实现,这种方式是自定义Schema的方式,可以在不知道Schema的时候使用。

2.详解

1).反射方式:

  • 定义case class,类似于定义DF的Schema

case class Person(name:String,age:Int)

  • 添加隐式转化
import spark.implicits._
  • 将数据转换为case class类型,并对其进行转换
val pdf=spark.sparkContext.textFile("file:///home/hadoop/app/spark-2.2.0-bin-2.6.0-cdh5.7.0/examples/src/main/resources/people.txt")
.map(_.split(","))
.map(x=>Person(x(0),x(1).trim.toInt))//数据可能有空格,对其进行去空格的操作
.toDF()

2)编程实现

这个的操作较为复杂,我们可以先看看源码中的参数定义

def createDataFrame(rowRDD: RDD[Row], schema: StructType): DataFrame = {
    createDataFrame(rowRDD, schema, needsConversion = true)
  }

我们可以发现,这个方法需要两个参数分别是:rowRDD: RDD[Row]和 schema: StructType,我们先来查看一下StructType这个类的构造函数

 case class StructField(
    name: String,//字段名字
    dataType: DataType,//字段类型
    nullable: Boolean = true,//是否为空
    metadata: Metadata = Metadata.empty)

我们可以发现参数中有两个默认参数是不用我们写的,name: String 和dataType: DataType是需要我们传入的,从代码中看出我们需要得到schema就要定义name和DataType。理论先讲到这里,下面可以看一个实现schema的例子:

val schemaString = "name age"
val fields = schemaString.split(" ")
.map(fieldName => StructField(fieldName, StringType, nullable = true))
//从代码中可以看出使用 StructField类对每个自定义的类型进行处理,并且都将它们定义为StringType类型。
注:可以有任意类型,如LongType等等

如何获得ROW,就相对简单一点,将数据进行切分,将每个数据顺序与另一个Schema的顺序相对应

val pdf2=spark.sparkContext.textFile("/home/hadoop/app/spark-2.2.0-bin-2.6.0-cdh5.7.0/examples/src/main/resources/people.txt")
.map(_.split(",")).map(attributes => Row(attributes(0), attributes(1).trim))

最后将这两个参数传入到createDataFrame这个算子中

val peopleDF = spark.createDataFrame(pdf2, schema)

整体代码如下

val pdf2=spark.sparkContext.textFile("/home/hadoop/app/spark-2.2.0-bin-2.6.0-cdh5.7.0/examples/src/main/resources/people.txt")
.map(_.split(",")).map(attributes => Row(attributes(0), attributes(1).trim))
val schemaString = "name age"
val fields = schemaString.split(" ")
.map(fieldName => StructField(fieldName, StringType, nullable = true))
val schema = StructType(fields)
val peopleDF = spark.createDataFrame(pdf2, schema)

3.总结

这两种方法各有优劣,希望大家根据场景,及自己的爱好权衡使用。

猜你喜欢

转载自blog.csdn.net/weixin_39216383/article/details/80494630