spark基础之RDD和DataFrame的转换方式

一 通过定义Case Class,使用反射推断Schema

定义Case Class,在RDD的转换过程中使用Case Class可以隐式转换成SchemaRDD,然后再注册成表,然后就可以利用sqlContext或者SparkSession操作了。

我们给出一个电影测试数据film.txt,定一个Case Class(Film),然后将数据文件读入后隐式转换成SchemeRDD:film,并将film在SparkSession中注册,最后对表进行查询

1.1 上传测试数据

hdfs dfs -put /opt/data/film.txt /user/hadoop

1.2 定义SparkSession,静态导入其所有成员

val session = SparkSession.builder()
    .appName("Case Class To Define RDD")
    .config("spark.some.config.option", "some-value")
    .master("local[*]")
    .getOrCreate()

import session.implicits._

1.3 定义Film类,读入数据并创建视图

val filmRdd = session.sparkContext.textFile("hdfs://hdfs-cluster/user/hadoop/film.txt")
val filmDF = filmRdd
    .map(_.split(","))
    .map(fields => Film(fields(0),fields(1),fields(2),fields(3),fields(4).trim.toInt,fields(5),fields(6).trim.toFloat))
    .toDF()
filmDF.createOrReplaceTempView("film")

1.4 查询分数大于5.0的电影

val results =session.sql("SELECT name,director,style,score FROM film WHERE score > 5.0")

 

1.5 对获取到的Dataset进行映射,因为不知道数据的schema,所以我们需要getAs方法获取对应的列,并将每一行结果返回,最后打印结果

val filmDS = results.map(film => {
    val name = film.getAs[String]("name")
    val director = film.getAs[String]("director")
    val style = film.getAs[String]("style")
    val score = film.getAs[Float]("score")
    (name,director,style,score)
})
filmDS.show(10)

 

二 通过编程接口,定义Schema,并应用到RDD上

通过使用createDataFrame定义RDD,通常有三个步骤

# 创建初始RDD

# 构建Row类型的RDD

# 构建该RDD对应的schema

然后调用createDataFrame方法

2.1 创建SparkSession,静态导入成员

val session = SparkSession.builder()
    .appName("Create DataFrame API To Define RDD")
    .config("spark.some.config.option", "some-value")
    .master("local[*]")
    .getOrCreate()

import session.implicits._

 

 

2.2HDFS 读取数据,构建初始RDD

val filmRdd = session.sparkContext.textFile("hdfs://hdfs-cluster/user/hadoop/film.txt")

 

2.3构建Row类型的RDD

val rowRdd = filmRdd
    .map(_.split(","))
    .map(fields =>
        Row(fields(0),fields(1),fields(2),fields(3),fields(4).trim.toInt,fields(5),fields(6).trim.toFloat)
    )

 

2.4 构建该RDD对应的schema

// 这里的数据类型必须和数据源所有类型对应
val schema:StructType = StructType(Array(
    StructField("filmid",StringType),
    StructField("director",StringType),
    StructField("name",StringType),
    StructField("release_time",StringType),
    StructField("box_office",IntegerType),
    StructField("style",StringType),
    StructField("score",FloatType)
))

 

2.5 创建DataFrame,并创建汇或者替换视图,然后查询查询分数大于5.0的电影

val filmDF = session.createDataFrame(rowRdd,schema)
filmDF.createOrReplaceTempView("film")
val results = session.sql("SELECT name,director,style,score FROM film WHERE score > 5.0")

 

2.6 获取结果,进行展示

val filmDS = results.map(film => {
    val name = film.getAs[String]("name")
    val director = film.getAs[String]("director")
    val style = film.getAs[String]("style")
    val score = film.getAs[Float]("score")
    (name,director,style,score)
})
filmDS.show(10)

 

 

 

 

你可能感兴趣的:(大数据/spark)