【Spark SQL】- RDD、DataFrame、Dataset三者之间相互转换 ⭐⭐⭐

1 . 转换方法

  • DataFrame 、Dataset 转 RDD
    在这里插入图片描述
  • RDD 转 DataFrame
    在这里插入图片描述
  • RDD 转 Dataset
    在这里插入图片描述
  • Dataset 转 DataFrame
    在这里插入图片描述
  • DataFrame 转 Dataset
    在这里插入图片描述

2. 代码案例

  • RDD To Dataset

package practice.dataset

import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.sql.{Dataset, SparkSession}

/**
  * @author 王天赐
  * @create 2019-06-10 14:58
  */
object RDDToDataset {
	// 注意 需要定义 类型匹配 , 否则无法使用 并且 特别注意 类型匹配的需要放在 main 方法外面
	case class Person(name : String, age : Int) extends Serializable

	def main(args: Array[String]): Unit = {

		// 创建SparkConf 以及SparkContext , 并设置 Master 为本地运行模式
		val conf = new SparkConf()
			.setMaster("local")
			.setAppName("Create Dataset")
		val sc = new SparkContext(conf)
		// 设置日志输出等级
		sc.setLogLevel("WARN")

		// 创建SparkSession
		val spark = SparkSession
			.builder()
			.appName("SPARK SESSION")
			.config("spark.some.config.option", "some-value")
			.getOrCreate()

		/**
		  * people.txt
		  * Michael, 29
		  * Andy, 30
		  * Justin, 19
		  */
		// 读取txt文件数据
		val rdd = sc.textFile("SparkSql/src/main/resources/people.txt")

		/* RDD TO Dataset*/

		// 1.导入隐式转换
		import spark.implicits._
		// 2.在 main 方法外定义用于匹配的类 (注意 一定要继承Serializable,用于序列化数据):
		// case class Person(name : String, age : Int) extends Serializable

		// 3.对 RDD 中的数据进行切分 , 并且封装进 Person 对象中
		val testDS = rdd.map{ line =>
			val datas = line.split(",")
			Person(datas(0), datas(1).trim.toInt) // 这里 写不写 new 都可以
		}.toDS()

		// 显示 数据
		testDS.show()

		spark.stop()
		sc.stop()
	}
}

  • 核心代码
		// 1.导入隐式转换
		import spark.implicits._
		// 2.在 main 方法外定义用于匹配的类 (注意 一定要继承Serializable,用于序列化数据):
		// case class Person(name : String, age : Int) extends Serializable

		// 3.对 RDD 中的数据进行切分 , 并且封装进 Person 对象中
		val testDS = rdd.map{ line =>
			val datas = line.split(",")
			Person(datas(0), datas(1).trim.toInt) // 这里 写不写 new 都可以
		}.toDS()
  • RDD TO DataFrame

package practice.dataframe

import org.apache.spark.rdd.RDD
import org.apache.spark.sql.{Dataset, Row, SparkSession}
import org.apache.spark.{SparkConf, SparkContext}

/**
  * RDD 和 DataFrame 之间的相互转换
  *
  * @author 王天赐
  * @create 2019-06-07 20:56
  */
object RDDToDataFrame {

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

	def RDDTODataFrame(spark: SparkSession, sc: SparkContext) {

		// 读取数据
		val rdd = sc.textFile("SparkSql/src/main/resources/people.txt")

		// 1.导入隐式转换
		import spark.implicits._

		// 2.将 RDD 中的数据分割 , 并且转换为 DataFrame
		val personRDD : RDD[Tuple3[String, String, String]] = rdd
			.map{ line =>
				val datas = line.split(",")
				(datas(0), datas(1), datas(1))
			}
		// 3.将 RDD 转换成 DataFrame
		// 【重点】其实在 第二步已经可以直接转换 ,但是 这里我没有直接转换的原因是 想展示 返回值的类型
		// 可以看到的是 , RDD 必须是 Tuple 类型的才可以 直接转换成 DataFrame(Dataset[Row])
		// 并且 字段是 对应的是 Tuple 的数据个数 , 如上 ,我的值类型是  Tuple3 所以 , 对应的 DF() 字段也应该是 3
		// 否则会出现匹配问题
		val personDF : Dataset[Row]= personRDD.toDF("name", "age", "newage")

		// 显示所有数据
		personDF.show()
		// 打印结构
		personDF.printSchema()
		// 显示 name 列的数据
		personDF.select("name").show()
		// 显示年龄大于 21 的用户的数据
		personDF.filter($"age" > 21).show()
		// 根据年龄分组排序
		personDF.groupBy("age").count().show()
	}


	def main(args: Array[String]): Unit = {

		val conf = new SparkConf()
			.setAppName("RDD TO DataFrame")
			.setMaster("local")

		val sc = new SparkContext(conf)
		// 设置日志输出等级
		sc.setLogLevel("WARN")

		// 创建 SparkSession 对象
		val spark = SparkSession
			.builder()
			.appName("SPARK SESSION")
			.config("spark.some.config.option", "some-value")
			.getOrCreate()

		RDDTODataFrame(spark, sc)

		spark.stop()
		sc.stop()
	}
}

  • 核心代码
		// 1.导入隐式转换
		import spark.implicits._

		// 2.将 RDD 中的数据分割 , 并且转换为 DataFrame
		val personRDD : RDD[Tuple3[String, String, String]] = rdd
			.map{ line =>
				val datas = line.split(",")
				(datas(0), datas(1), datas(1))
			}
		// 3.将 RDD 转换成 DataFrame
		// 【重点】其实在 第二步已经可以直接转换 ,但是 这里我没有直接转换的原因是 想展示 返回值的类型
		// 可以看到的是 , RDD 必须是 Tuple 类型的才可以 直接转换成 DataFrame(Dataset[Row])
		// 并且 字段是 对应的是 Tuple 的数据个数 , 如上 ,我的值类型是  Tuple3 所以 , 对应的 DF() 字段也应该是 3
		// 否则会出现匹配问题
		val personDF : Dataset[Row]= personRDD.toDF("name", "age", "newage")

【重点] 其实在 第二步已经可以直接转换 ,但是 这里我没有直接转换的原因是 想展示 返回值的类型
可以看到的是 , RDD 必须是 Tuple 类型的才可以 直接转换成 DataFrame(Dataset[Row])
并且 字段是 对应的是 Tuple 的数据个数 , 如上 ,我的值类型是 Tuple3 所以 , 对应的 DF() 字段也应该是 3

  • Dataset 、DataFrame To RDD 以及 Dataset To DataFrame

Dataset => DataFrame => RDD 从左到右转换都比较简单

val rdd02 = testDS.rdd
val rdd03 = personDF.rdd
val df01 = testDS.toDF("hello" , "hi") // 可以指定字段名,但是字段数目要匹配
val df02 = testDS.toDF
  • DataFrame To Dataset
package practice.dataframe

import org.apache.spark.sql.functions.col
import org.apache.spark.sql.{Column, Dataset, Row, SparkSession}
import org.apache.spark.{SparkConf, SparkContext}
/**
  * @author 王天赐
  * @create 2019-06-04 14:43
  */
object CreateDataFrame {

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

	def CreateDataFrameByScala(spark: SparkSession , df : Dataset[Row]): Unit ={

		// 1.第一步 隐式转换
		import spark.implicits._
		// 2.第二步 :case class Person(name : String , age : Int) extends Serializable
		// 3.第三步 : 直接转换即可
		val ds = df.as[Person]

		ds.show()

	}

	def main(args: Array[String]): Unit = {

		// 创建SparkConf 以及SparkContext , 并设置 Master 为本地运行模式
		val conf = new SparkConf()
			.setMaster("local")
			.setAppName("Create Dataset")
		val sc = new SparkContext(conf)
		// 设置日志输出等级
		sc.setLogLevel("WARN")

		// 创建SparkSession
		val sparkSession = SparkSession
			.builder()
			.appName("SPARK SESSION")
			.config("spark.some.config.option", "some-value")
			.getOrCreate()

		// 读取Json数据
		var df = sparkSession.read.json("SparkSql/src/main/resources/people.json")

		/* 调用 */
		CreateDataFrameByScala(sparkSession , df)

		// 关闭SparkSessions
		sparkSession.stop()
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

兀坐晴窗独饮茶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值