【spark-sql】DataFrame和RDD的互操作

35 篇文章 1 订阅
19 篇文章 0 订阅

Dataset 是一个分布式的数据集
DataFrame ,是以列(列名,列的类型,列值)的形式构成的分布式数据集(Dataset),按照列赋予不同的名称。可以理解为一张表
例如:
student 表 有id,name等列名,列类型
id:int
name:string
city:string

一、DataFrame API基本操作
package com.kinglone.bigscala

import org.apache.spark.sql.SparkSession

/**
 * DataFrame API基本操作
 */
object DataFrameApp {

  def main(args: Array[String]) {

    val spark = SparkSession.builder().appName("DataFrameApp").master("local[2]").getOrCreate()

    // 将json文件加载成一个dataframe
    val peopleDF = spark.read.format("json").load("file:///Users/rocky/data/people.json")

    // 输出dataframe对应的schema信息
    peopleDF.printSchema()

    // 输出数据集的前20条记录
    peopleDF.show()

    //查询某列所有的数据: select name from table
    peopleDF.select("name").show()

    // 查询某几列所有的数据,并对列进行计算: select name, age+10 as age2 from table
    peopleDF.select(peopleDF.col("name"), (peopleDF.col("age") + 10).as("age2")).show()

    //根据某一列的值进行过滤: select * from table where age>19
    peopleDF.filter(peopleDF.col("age") > 19).show()

    //根据某一列进行分组,然后再进行聚合操作: select age,count(1) from table group by age
    peopleDF.groupBy("age").count().show()

    spark.stop()
  }

}

二、DataFrame API 操作案例实战

学生信息统计案例
数据格式:
在这里插入图片描述
统计代码:

package com.kinglone.bigscala

import org.apache.spark.sql.SparkSession

/**
 * DataFrame中的操作操作
 */
object DataFrameCase {

  def main(args: Array[String]) {
    val spark = SparkSession.builder().appName("DataFrameRDDApp").master("local[2]").getOrCreate()

    // RDD ==> DataFrame
    val rdd = spark.sparkContext.textFile("file:///Users/rocky/data/student.data")

    //注意:需要导入隐式转换
    import spark.implicits._
    val studentDF = rdd.map(_.split("\\|")).map(line => Student(line(0).toInt, line(1), line(2), line(3))).toDF()

    //---------------show默认只显示前20条
    studentDF.show 图一
    studentDF.show(30)  ## 指定显示条数
    studentDF.show(30, false) ## 指定条数以及不截取数据  图二

    studentDF.take(10) ##前10条记录
    studentDF.first() # 返回第一条记录
    studentDF.head(3) 


    studentDF.select("email").show(30,false)  ## 指定查询列


    studentDF.filter("name=''").show
    studentDF.filter("name='' OR name='NULL'").show


    //name以M开头的人
    studentDF.filter("SUBSTR(name,0,1)='M'").show

    studentDF.sort(studentDF("name")).show
    studentDF.sort(studentDF("name").desc).show

    studentDF.sort("name","id").show
    studentDF.sort(studentDF("name").asc, studentDF("id").desc).show # 按name升序 ,id降序

    studentDF.select(studentDF("name").as("student_name")).show ##改别名


    val studentDF2 = rdd.map(_.split("\\|")).map(line => Student(line(0).toInt, line(1), line(2), line(3))).toDF()
    // join  图三
    studentDF.join(studentDF2, studentDF.col("id") === studentDF2.col("id")).show

    spark.stop()
  }

  case class Student(id: Int, name: String, phone: String, email: String)

}

图一:
在这里插入图片描述
图二:
在这里插入图片描述
图三:
在这里插入图片描述
通过脚本执行上面的代码比较方便查看结果

./spark-shell --master local[2] --jars /opt/mysql-connector-java-5.1.22-bin.jar
三、Dataset API 操作

数据格式:
在这里插入图片描述
代码:

package com.kinglone.bigscala

import org.apache.spark.sql.SparkSession

/**
 * Dataset操作
 */
object DatasetApp {

  def main(args: Array[String]) {
    val spark = SparkSession.builder().appName("DatasetApp")
      .master("local[2]").getOrCreate()

    //注意:需要导入隐式转换
    import spark.implicits._

    val path = "file:///Users/rocky/data/sales.csv"

    //spark如何解析csv文件?  解析头部
    val df = spark.read.option("header","true").option("inferSchema","true").csv(path)
    df.show  ###图一
     // DataFrame 转换成  Dataset
    val ds = df.as[Sales]
    ds.map(line => line.itemId).show


    spark.sql("seletc name from person").show

    //df.seletc("name")
    df.select("nname") ## 假如DataFrame 字母写错编译不报错,执行时报错
	//假如Dataset 写错字母,编译时就报错
    ds.map(line => line.itemId)

    spark.stop()
  }

  case class Sales(transactionId:Int,customerId:Int,itemId:Int,amountPaid:Double)
}

图一:
在这里插入图片描述
总结:
DataFrame 是强类型,假如DataFrame 字母写错编译不报错,执行时报错
Dataset是弱类型,假如Dataset 写错字母,编译时就报错

三、DataFrame和RDD的互操作

DataFrame和RDD的互操作 的两种方式
1)反射方式:cass class 前提:事先需要知道字段,字段类型
2)编程方式:Row 如果第一种情况不满足(事先不知道列)
3)选型:优先考虑第一种方式

/**
  * DataFrame和RDD的互操作
  */
object DataFrameRDDApp {

  def main(args: Array[String]): Unit = {
    val spark = SparkSession.builder().appName("DataFrameRDDApp").master("local[2]").getOrCreate()
    //1.反射的方式
    //inferReflection(spark)
	//2.编程的方式
	program(spark)
    spark.close()
  }
	def program(spark: SparkSession): Unit = {
    // RDD ==> DataFrame
    val rdd = spark.sparkContext.textFile("file:///D://test/infos.txt")
    //转换成Row
    val infoRDD = rdd.map(_.split(",")).map(line => Row(line(0).toInt, line(1), line(2).toInt))
    //指定Row里的数据结构
    val structType = StructType(Array(StructField("id", IntegerType, true),
      StructField("name", StringType, true),
      StructField("age", IntegerType, true)))

    val infoDF = spark.createDataFrame(infoRDD,structType)
    infoDF.printSchema()
    infoDF.show()

    //通过df的api进行操作
    infoDF.filter(infoDF.col("age") > 30).show

    //通过sql的方式进行操作
    infoDF.createOrReplaceTempView("infos")
    spark.sql("select * from infos where age > 30").show()
  }

  def inferReflection(spark: SparkSession) = {
    // RDD ==> DataFrame
    val rdd = spark.sparkContext.textFile("file:///D://test/infos.txt")
    //注意:需要导入隐式转换
    import spark.implicits._
    //转换成DataFrame
    val infoDF = rdd.map(_.split(",")).map(line => Info(line(0).toInt, line(1), line(2).toInt)).toDF()

    infoDF.show()
    //查询年龄大于30的
    infoDF.filter(infoDF.col("age") > 30).show
    //将DataFrame转换成一张表来查询
    infoDF.createOrReplaceTempView("infos")
    spark.sql("select * from infos where age > 30").show()
  }
  //定义一个类
  case class Info(id: Int, name: String, age: Int)
}

在这里插入图片描述
数据格式:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值