Spark DataFrame与RDD互操作

DataFrame与RDD的互操作

1.Spark SQL支持将现有的RDDs转换为数据集的两种不同的方法。第一个方法使用反射来推断一个包含特定对象类型的RDD的模式。这种基于反射的方法会导致更简洁的代码,但要在编写Spark应用程序时就已经知道了Schema。

2.创建数据集的第二种方法是通过一个编程接口,它允许您构造一个模式,然后将其应用到现有的RDD中。虽然这个方法比较冗长,但是它在运行时构造数据集并且它们的类型直到运行时才知道。

(一)反射方式
Spark SQL的Scala接口支持自动将包含case类的RDD转换为DataFrame。 case类定义了表的Schema。 对case类的参数的名称是使用反射读取的,并成为列的名称。 Case类也可以嵌套或包含复杂的类型,例如Seqs或数组。 这个RDD可以隐式地转换为一个DataFrame,然后将其注册为一个表。 表可以在后续的SQL语句中使用。
import org.apache.log4j.{Level, Logger}
import org.apache.spark.sql.SparkSession

/**
  * Created by **** 2017/12/23 10:47
  * DataFrame和RDD的互操作
  *   (一)方式方式:使用反射来推断包含了特定数据类型的RDD的元数据(case class)
  *                 使用DataFrame API或者sql方式编程
  */
object DataFrameRDDApp {

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

    //RDD ==> DataFrame
    val peopleRDD = spark.sparkContext.textFile("src/data/people.txt")

    // 注意:需要导入隐式转换  RDD.toDF ==> DataFrame
    import spark.implicits._
    val peopleDF = peopleRDD.map(_.split(","))
      .map(line =>
        People(line(0).toInt,line(1),line(2).toInt)
      ).toDF()

    peopleDF.printSchema()
    peopleDF.show()

    // 使用DataFrame API编程
    peopleDF.filter(peopleDF.col("age")>30).show()

    //使用SQL方式编程,要先创建临时表
    peopleDF.createOrReplaceTempView("people")
    spark.sql("select * from people where age > 30").show()

    spark.stop()

  }

  case class People(id: Int, name: String, age: Int)

  def SetLogger() = {
    Logger.getLogger("org").setLevel(Level.OFF)
    Logger.getLogger("com").setLevel(Level.OFF)
    System.setProperty("spark.ui.showConsoleProgress", "false")
    Logger.getRootLogger().setLevel(Level.OFF);
  }

}

(二) 以编程方式指定模式

当case类不能提前定义时(例如,记录的结构是在一个字符串中编码的,或者文本数据集将被解析,不同的用户将对字段进行不同的预测),一个DataFrame可以用3个步骤来创建。

  1. 从原始的RDD中创建一个行;
  2. 创建在第1步中创建的RDD中所表示的结构类型的结构类型。Create the schema represented by a StructType matching the structure of Rows in the RDD created in Step 1.
  3. 通过SparkSession提供的createDataFrame方法将模式应用到行的RDD中。

 val peopleRDD = spark.sparkContext.textFile("src/data/people.txt")

    val rowRDD = peopleRDD.map(_.split(",")).map(line =>
        Row(line(0).toInt, line(1), line(2).toInt)
      )

    val structType = StructType(
      Array(
        StructField("id",IntegerType,true),
        StructField("name",StringType,true),
        StructField("age",IntegerType,true)
      ))

    val peopleDF = spark.createDataFrame(rowRDD,structType)

    peopleDF.printSchema()
    peopleDF.show()


你可能感兴趣的:(spark,DataFrame)