RDD转换DataFrame
Spark SQL有两种方法将RDD转为DataFrame。
1. 使用反射机制,推导包含指定类型对象RDD的schema。这种基于反射机制的方法使代码更简洁,而且如果你事先知道数据schema,推荐使用这种方式;
2. 编程方式构建一个schema,然后应用到指定RDD上。这种方式更啰嗦,但如果你事先不知道数据有哪些字段,或者数据schema是运行时读取进来的,那么你很可能需要用这种方式。
利用反射推导schema
Spark SQL的Scala接口支持自动将包含case class对象的RDD转为DataFrame。对应的case class定义了表的schema。case class的参数名通过反射,映射为表的字段名。case class还可以嵌套一些复杂类型,如Seq和Array。RDD隐式转换成DataFrame后,可以进一步注册成表。随后,你就可以对表中数据使用SQL语句查询了。
// sc 是已有的 SparkContext 对象
val sqlContext = new org.apache.spark.sql.SQLContext(sc)
// 为了支持RDD到DataFrame的隐式转换
import sqlContext.implicits._
// 定义一个case class.
// 注意:Scala 2.10的case class最多支持22个字段,要绕过这一限制,
// 你可以使用自定义class,并实现Product接口。当然,你也可以改用编程方式定义schema
case class Person(name: String, age: Int)
// 创建一个包含Person对象的RDD,并将其注册成table
val people = sc.textFile("examples/src/main/resources/people.txt").map(_.split(",")).map(p => Person(p(0), p(1).trim.toInt)).toDF()
people.registerTempTable("people")
// sqlContext.sql方法可以直接执行SQL语句
val teenagers = sqlContext.sql("SELECT name, age FROM people WHERE age >= 13 AND age <= 19")
// SQL查询的返回结果是一个DataFrame,且能够支持所有常见的RDD算子
// 查询结果中每行的字段可以按字段索引访问:
teenagers.map(t => "Name: " + t(0)).collect().foreach(println)
// 或者按字段名访问:
teenagers.map(t => "Name: " + t.getAs[String]("name")).collect().foreach(println)
// row.getValuesMap[T] 会一次性返回多列,并以Map[String, T]为返回结果类型
teenagers.map(_.getValuesMap[Any](List("name", "age"))).collect().foreach(println)
// 返回结果: Map("name" -> "Justin", "age" -> 19)
编程方式定义Schema
如果不能事先通过case class定义schema(例如,记录的字段结构是保存在一个字符串,或者其他文本数据集中,需要先解析,又或者字段对不同用户有所不同),那么你可能需要按以下三个步骤,以编程方式的创建一个DataFrame:
- 从已有的RDD创建一个包含Row对象的RDD
- 用StructType创建一个schema,和步骤1中创建的RDD的结构相匹配
- 把得到的schema应用于包含Row对象的RDD,调用这个方法来实现这一步:SQLContext.createDataFrame
For example:
例如:
// sc 是已有的SparkContext对象
val sqlContext = new org.apache.spark.sql.SQLContext(sc)
// 创建一个RDD
val people = sc.textFile("examples/src/main/resources/people.txt")
// 数据的schema被编码与一个字符串中
val schemaString = "name age"
// Import Row.
import org.apache.spark.sql.Row;
// Import Spark SQL 各个数据类型
import org.apache.spark.sql.types.{StructType,StructField,StringType};
// 基于前面的字符串生成schema
val schema =
StructType(
schemaString.split(" ").map(fieldName => StructField(fieldName, StringType, true)))
// 将RDD[people]的各个记录转换为Rows,即:得到一个包含Row对象的RDD
val rowRDD = people.map(_.split(",")).map(p => Row(p(0), p(1).trim))
// 将schema应用到包含Row对象的RDD上,得到一个DataFrame
val peopleDataFrame = sqlContext.createDataFrame(rowRDD, schema)
// 将DataFrame注册为table
peopleDataFrame.registerTempTable("people")
// 执行SQL语句
val results = sqlContext.sql("SELECT name FROM people")
// SQL查询的结果是DataFrame,且能够支持所有常见的RDD算子
// 并且其字段可以以索引访问,也可以用字段名访问
results.map(t => "Name: " + t(0)).collect().foreach(println)
RDD转换DataFrame的更多相关文章
- RDD与DataFrame的转换
RDD与DataFrame转换1. 通过反射的方式来推断RDD元素中的元数据.因为RDD本身一条数据本身是没有元数据的,例如Person,而Person有name,id等,而record是不知道这些的 ...
- spark-DataFrame之RDD和DataFrame之间的转换
package cn.spark.study.core.mycode_dataFrame; import java.io.Serializable;import java.util.List; imp ...
- 045 RDD与DataFrame互相转换
一:RDD与DataFrame互相转换 1.总纲 二:DataFrame转换为RDD 1.rdd 使用schema可以获取DataFrame的schema 使用rdd可以获取DataFrame的数据 ...
- RDD、DataFrame、Dataset三者三者之间转换
转化: RDD.DataFrame.Dataset三者有许多共性,有各自适用的场景常常需要在三者之间转换 DataFrame/Dataset转RDD: 这个转换很简单 val rdd1=testDF. ...
- Spark之 RDD转换成DataFrame的Scala实现
依赖 <dependency> <groupId>org.apache.spark</groupId> <artifactId>spark-sql_2. ...
- 转】RDD与DataFrame的转换
原博文出自于: http://www.cnblogs.com/namhwik/p/5967910.html RDD与DataFrame转换1. 通过反射的方式来推断RDD元素中的元数据.因为RDD本身 ...
- sparksql 用反射的方式将rdd转换成dataset/dataframe
java public class ReflectionDemo { private static SparkConf conf = new SparkConf().setAppName(" ...
- RDD转换成为DataFrame
方式一: 通过case class创建DataFrames(反射) TestDataFrame1.scala package com.bky // 隐式类的导入 // 定义case class,相当于 ...
- RDD、DataFrame和DataSet的区别
原文链接:http://www.jianshu.com/p/c0181667daa0 RDD.DataFrame和DataSet是容易产生混淆的概念,必须对其相互之间对比,才可以知道其中异同. RDD ...
随机推荐
- Linq to entity 执行多个字段排序的方法
可以连续使用:OrderBy,ThenBy 或者 OrderByDescending,ThenByDescending var data = db.User .Where(u => u.User ...
- cocos2d-js Shader系列3:多重纹理 multiple textures multiple samplers
上一篇,我们学习了怎么便捷的控制sprite的颜色,而这个都是默认一个texture的,如果要实现类似mask的效果,或者更个性化的多纹理效果,怎么实现呢? 这就是这一节需要介绍的内容. 例如上图的效 ...
- lvalue & rvalue
https://www.youtube.com/watch?v=UTUdhjzws5g 作者:知乎用户链接:https://www.zhihu.com/question/50652989/answer ...
- Selenium+TestNG+Jenkins 框架图形化UML表示
- jQuery 绑定事件及移除绑定事件方法和元素事件列表
1.jQuery Event 事件: ready(fn); $(document).ready()注意在body中没有onload事件,否则该函数不能执行.在每个页面中可以有很多个函数被加载 ...
- Mac Mini 2011 mid 安装Ubuntu18.06.1 Server
在Mac mini上原来是安装的ESXi5.5, 时间比较久了, 因为内存只有8g, 跑不了几个vm, 逐渐闲置. 现在打算重新装一个Ubuntu Sever用来跑docker. 制作启动U盘 参考 ...
- node下使用jquery
node使用jquery的两种方式 在node下,使用jquery有两种方法: 使用jsdom模拟一个window对象 使用cheerio,cheerio只实现了jquery的dom部分功能,相当于j ...
- 使用Thrift让Python为Java提供服务
Thrift是基于TCP的,谷歌的GRPC是基于HTTP的.Thrift和GRPC都是比直接写个web接口进行调用更完美的方式,最明显的一点就是:我们可以定义结构体,避免了手动解析的过程. 但是,在将 ...
- Apache+PHP配置PATHINFO的一个小问题
使用ThinkPHP示例,设置'URL_MODEL' => 2,发现提示: No input file specified 应该是PATHINFO配置的问题,试 ...
- 【转】IOCP创建
转自:http://www.cmnsoft.com/wordpress/?p=248 感谢原作者.我在此整理一下: 完成端口(IOCP)是WINDOWS平台上特有的一种技术.要使用IOCP技术,就要用 ...