RDD->DF


简介:
DataFrame是分布式数据和数据结构组成的组织集合,概念等同于关系型数据库里的表(dataframe.registerTempTable("tablename")注册内存表)。
DataFrame的API支持Scala,java,Python,R。
r4vrf
SQLContext:
SparkSQL的所有方法都在SQLContext类或它的子类里,用SparkContext创建一个SQLContext:
[plain]   view plain   copy
  1. val sc: SparkContext // An existing SparkContext.  
  2. val sqlContext = new org.apache.spark.sql.SQLContext(sc)  
  3.   
  4. // 用来把RDD隐式转换为DF(DataFrame)  
  5. import sqlContext.implicits._  
也可以创建一个HiveContext,它是SQLContext的子集,额外提供了更完整的HiveQL解析器,Hive UDFs权限,并且可以直接读取Hive表的数据。
不需要重新配置Hive,原来的SQLContext使用的所有数据源HiveContext都可以直接使用。
也可以使用 spark.sql.dialect  来配置SQL方言,sparkSQL里的参数只有一个"sql",即使用SparkSQL,而HiveContext则可以把默认的"hiveql"改为“sql”。

创建一个DataFrame:
通过SQLContxt,可以从一个以存在的RDD、Hive表或数据源创建DF。
例:scala
[plain]   view plain   copy
  1. val sc: SparkContext // An existing SparkContext.  
  2. val sqlContext = new org.apache.spark.sql.SQLContext(sc)  
  3. val df = sqlContext.read.json("examples/src/main/resources/people.json")  
  4. // 显示字段和前五条数据  
  5. df.show(5)  

操作DataFrame:
例:scala
[plain]   view plain   copy
  1. val sc: SparkContext // An existing SparkContext.  
  2. val sqlContext = new org.apache.spark.sql.SQLContext(sc)  
  3.   
  4. // 创建 DataFrame  
  5. val df = sqlContext.read.json("examples/src/main/resources/people.json")  
  6.   
  7. // 显示 DataFrame 的字段和所有数据  
  8. df.show()  
  9. // age  name  
  10. // null Michael  
  11. // 30   Andy  
  12. // 19   Justin  
  13.   
  14. // 显示df的schema(以树形结构显示)  
  15. df.printSchema()  
  16. // root  
  17. // |-- age: long (nullable = true)  
  18. // |-- name: string (nullable = true)  
  19.   
  20. // 只查询"name"字段  
  21. df.select("name").show()  
  22. // name  
  23. // Michael  
  24. // Andy  
  25. // Justin  
  26.   
  27. // 查询name,age+1  
  28. df.select(df("name"), df("age") + 1).show()  
  29. // name    (age + 1)  
  30. // Michael null  
  31. // Andy    31  
  32. // Justin  20  
  33.   
  34. // 查询年龄 > 21  
  35. df.filter(df("age") > 21).show()  
  36. // age name  
  37. // 30  Andy  
  38.   
  39. // Count people by age  
  40. df.groupBy("age").count().show()  
  41. // age  count  
  42. // null 1  
  43. // 19   1  
  44. // 30   1  
这里是DataFrame的完整官方API:  DataFrame--API      DataFrame--函数引用

执行SQL:
SQLContext可以执行SQL并返回一个DataFrame:
[plain]   view plain   copy
  1. val sqlContext = ...  // An existing SQLContext  
  2. val df = sqlContext.sql("SELECT * FROM table")  

与RDD交互:
SparkSQL提供了两种方式把RDD转换为DataFrame
第一种通过反射(前提是知道schema),第二种通过提供的接口创建schema。
通过反射:
scala提供了一种通过case class把RDD转换为DataFrame,case clasee定义了表结构,通过反射的方式读取参数并转换为字段,case class也可以是嵌套的复杂序列或数组。这样RDD就可以隐式的转换为DataFrame,df再注册为内存表,就可以通过sql操作此表。
例:scala
[plain]   view plain   copy
  1. val sqlContext = new org.apache.spark.sql.SQLContext(sc)  
  2. // 用来隐式转换 RDD 为  DataFrame.  
  3. import sqlContext.implicits._  
  4.   
  5. // 通过 case class 定义schema.  
  6. // Note: Case classes 在 Scala 2.10 只支持最多 22 字段. 可以自定义接口突破这个限制.  
  7. case class Person(name: String, age: Int)  
  8.   
  9. // 创建一个Person的RDD并注册成表.  
  10. val people = sc.textFile("examples/src/main/resources/people.txt").map(_.split(",")).map(p => Person(p(0), p(1).trim.toInt)).toDF()  
  11. people.registerTempTable("people")  
  12.   
  13. // 通过sqlContext执行SQL操作内存表.  
  14. val teenagers = sqlContext.sql("SELECT name, age FROM people WHERE age >= 13 AND age <= 19")  
  15.   
  16. // SQL的查询结果是DataFrame.  
[plain]   view plain   copy
  1. //字段可以通过下标来获得  
  2. teenagers.map(t => "Name: " + t(0)).collect().foreach(println)  
  3.   
  4. // 或用字段名:  
  5. teenagers.map(t => "Name: " + t.getAs[String]("name")).collect().foreach(println)  
  6.   
  7. \\
  8. teenagers.map(_.getValuesMap[Any](List("name", "age"))).collect().foreach(println)  
  9. // Map("name" -> "Justin", "age" -> 19)  
反射实例:

通过接口自定义schema:
当某些情况下case class不能提前定义时,就用这种方法,一般分三步:
1.通过原始RDD创建RDD的Rows
2.通过StructType匹配RowS里的结构创建schema
3.通过SQLContext提供的createDataFrame(row,schema)方法创建DataFrame
例:scala
[plain]   view plain   copy
  1. // sc is an existing SparkContext.  
  2. val sqlContext = new org.apache.spark.sql.SQLContext(sc)  
  3.   
  4. // 创建 RDD  
  5. val people = sc.textFile("examples/src/main/resources/people.txt")  
  6.   
  7. // The schema is encoded in a string  
  8. val schemaString = "name age"  
  9.   
  10. // Import Row.  
  11. import org.apache.spark.sql.Row;  
  12.   
  13. // Import Spark SQL data types  
  14. import org.apache.spark.sql.types.{StructType,StructField,StringType};  
  15.   
  16. // 通过接口定义schema  
  17. val schema =  
  18.   StructType(  
  19.     schemaString.split(" ").map(fieldName => StructField(fieldName, StringType, true)))  
  20.   
  21. // 把RDD (people) 转换为 Rows.  
  22. val rowRDD = people.map(_.split(",")).map(p => Row(p(0), p(1).trim))  
  23.   
  24. // Apply the schema to the RDD.  
  25. val peopleDataFrame = sqlContext.createDataFrame(rowRDD, schema)  
  26.   
  27. // df注册内存表.  
  28. peopleDataFrame.registerTempTable("people")  
  29.   
  30. // sqlContext执行SQL返回结果df.  
  31. val results = sqlContext.sql("SELECT name FROM people")  
  32. <pre name="code" class="plain">// SQL的查询结果是DataFrame.  
[plain]   view plain   copy
  1. //字段可以通过下标来获得  
results.map(t => "Name: " + t(0)).collect().foreach(println)
通过StructType直接指定Schema

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值