RDD转换为DataSet和DataFrame

1、Spark SQL支持两种将现有rdd转换为Datasets的方法。第一种方法使用反射来推断包含特定类型对象的RDD的schema。在编写Spark应用程序时,如果您已经了解了schema,那么这种基于反射的方法可以产生更简洁的代码。
2、创建Datasets的第二种方法是通过一个编程接口,该接口允许您构造一个schema,然后将它应用到现有的RDD。虽然此方法更加详细,但当列及其类型直到运行时才知道时,它允许您构造Datasets。

1、反射推断

Spark SQL的Scala接口支持将包含case类的RDD自动转换为DataFrame。case类定义了表的schema。使用反射读取case类的参数名称,并将其作为列的名称。Case类也可以嵌套或包含复杂类型,如Seqs或Arrays。这个RDD可以隐式转换为一个DataFrame,然后注册为一个表。表可以在后续的SQL语句中使用。
采用反射的方式推断出Schema信息,将RDD转换为Dataset和DataFrame,具体步骤:
1、RDD[CaseClass]
2、caseclassRDD.toDF() / caseclassRDD.toDS()

将RDD中数据类型变为CaseClass样例类,直接调用toDF或toDS即可转换。

		// TODO: 构建SparkSession实例对象, 对SparkContext封装,得层还是SparkContext
		val spark: SparkSession = SparkSession
			.builder()    // 使用建造者模式构建对象
			.appName(this.getClass.getSimpleName.stripSuffix("$"))
			.master("local[3]")
			.getOrCreate()
		// For implicit conversions like converting RDDs to DataFrames
		import spark.implicits._


		// 读取电影评分数据u.data, 每行数据有四个字段,使用制表符分割
		// user id | item id | rating | timestamp.
		val ratingsRDD: RDD[String] = spark.sparkContext.textFile("datas/ml-100k/u.data", minPartitions = 2)


		// 转换数据
		val mrsRDD: RDD[MovieRating] = ratingsRDD
	    	.filter(line => null != line && line.trim.split("\t").length == 4)
			.mapPartitions{iter =>
				iter.map{line =>
					// 拆箱操作, Python中常用
					val Array(userId, itemId, rating, timestamp) = line.trim.split("\t")
					// val arr = line.trim.split("\t")
					// 返回MovieRating实例对象
					MovieRating(userId, itemId, rating.toDouble, timestamp.toLong)
				}
			}

		// 将RDD转换为DataFrame和Dataset
		val mrsDF: DataFrame = mrsRDD.toDF()
		mrsDF.printSchema()
		mrsDF.show(10)


		val mrsDS = mrsRDD.toDS()
		mrsDS.printSchema()
		mrsDS.show(10)

2、自定义Schema

当case类不能提前定义时(例如,记录的结构被编码在字符串中,或者文本数据集将被解析,字段将被不同的用户以不同的方式投影),可以创建一个DataFrame
可以手动编程定义Schema信息,应用到已存在的RDD上,转换为DataFrame,具体步骤:
1、Create an RDD of Rows from the original RDD;
RDD[Row]
2、Create the schema represented by a StructType matching the structure of Rows in the RDD created in Step 1.
schema
3、Apply the schema to the RDD of Rows via createDataFrame method provided by SparkSession.
调用sparkSession中createDataFrame函数,传递rowsRDD和schema信息

		// TODO: 构建SparkSession实例对象, 对SparkContext封装,得层还是SparkContext
		val spark: SparkSession = SparkSession
			.builder()    // 使用建造者模式构建对象
			.appName(this.getClass.getSimpleName.stripSuffix("$"))
			.master("local[3]")
			.getOrCreate()
		// For implicit conversions like converting RDDs to DataFrames
		import spark.implicits._


		// 读取电影评分数据u.data, 每行数据有四个字段,使用制表符分割
		// user id | item id | rating | timestamp.
		val ratingsRDD: RDD[String] = spark.sparkContext.textFile("datas/ml-100k/u.data", minPartitions = 2)


		// a. RDD[Row]
		val rowsRDD: RDD[Row] = ratingsRDD.mapPartitions{ iter =>
			iter.map{line =>
				// 拆箱操作, Python中常用
				val Array(userId, itemId, rating, timestamp) = line.trim.split("\t")
				// 返回Row实例对象
				Row(userId, itemId, rating.toDouble, timestamp.toLong)
			}
		}

		// b. schema
		val rowSchema: StructType = StructType(
			Array(
				StructField("userId", StringType, nullable = true),
				StructField("itemId", StringType, nullable = true),
				StructField("rating", DoubleType, nullable = true),
				StructField("timestamp", LongType, nullable = true)
			)
		)

		// c. 应用函数createDataFrame
		val ratingDF: DataFrame = spark.createDataFrame(rowsRDD, rowSchema)
		ratingDF.printSchema()
		ratingDF.show(10, truncate = false)


		// TODO: 将DataFrame转换为Dataset,指定泛型
		val ratingsDS: Dataset[MovieRating] = ratingDF.as[MovieRating]
		ratingsDS.show()
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值