原博文出自于:  http://www.cnblogs.com/BYRans/p/5003029.html        感谢!

Spark SQL 之 DataFrame


转载请注明出处:http://www.cnblogs.com/BYRans/

概述(Overview)

Spark SQL是Spark的一个组件,用于结构化数据的计算。Spark SQL提供了一个称为DataFrames的编程抽象,DataFrames可以充当分布式SQL查询引擎。

DataFrames

DataFrame是一个分布式的数据集合,该数据集合以命名列的方式进行整合。DataFrame可以理解为关系数据库中的一张表,也可以理解为R/Python中的一个data frame。DataFrames可以通过多种数据构造,例如:结构化的数据文件、hive中的表、外部数据库、Spark计算过程中生成的RDD等。
DataFrame的API支持4种语言:Scala、Java、Python、R。

入口:SQLContext(Starting Point: SQLContext)

Spark SQL程序的主入口是SQLContext类或它的子类。创建一个基本的SQLContext,你只需要SparkContext,创建代码示例如下:

  • Scala
  1. val sc: SparkContext // An existing SparkContext.
  2. val sqlContext = new org.apache.spark.sql.SQLContext(sc)
  • Java
  1. JavaSparkContext sc = ...; // An existing JavaSparkContext.
  2. SQLContext sqlContext = new org.apache.spark.sql.SQLContext(sc);

除了基本的SQLContext,也可以创建HiveContext。SQLContext和HiveContext区别与联系为:

  • SQLContext现在只支持SQL语法解析器(SQL-92语法)
  • HiveContext现在支持SQL语法解析器和HiveSQL语法解析器,默认为HiveSQL语法解析器,用户可以通过配置切换成SQL语法解析器,来运行HiveSQL不支持的语法。
  • 使用HiveContext可以使用Hive的UDF,读写Hive表数据等Hive操作。SQLContext不可以对Hive进行操作。
  • Spark SQL未来的版本会不断丰富SQLContext的功能,做到SQLContext和HiveContext的功能容和,最终可能两者会统一成一个Context

HiveContext包装了Hive的依赖包,把HiveContext单独拿出来,可以在部署基本的Spark的时候就不需要Hive的依赖包,需要使用HiveContext时再把Hive的各种依赖包加进来。

SQL的解析器可以通过配置spark.sql.dialect参数进行配置。在SQLContext中只能使用Spark SQL提供的”sql“解析器。在HiveContext中默认解析器为”hiveql“,也支持”sql“解析器。

创建DataFrames(Creating DataFrames)

使用SQLContext,spark应用程序(Application)可以通过RDD、Hive表、JSON格式数据等数据源创建DataFrames。下面是基于JSON文件创建DataFrame的示例:

  • Scala
  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. // Displays the content of the DataFrame to stdout
  5. df.show()
  • Java
  1. JavaSparkContext sc = ...; // An existing JavaSparkContext.
  2. SQLContext sqlContext = new org.apache.spark.sql.SQLContext(sc);
  3. DataFrame df = sqlContext.read().json("examples/src/main/resources/people.json");
  4. // Displays the content of the DataFrame to stdout
  5. df.show();

DataFrame操作(DataFrame Operations)

DataFrames支持Scala、Java和Python的操作接口。下面是Scala和Java的几个操作示例:

  • Scala
  1. val sc: SparkContext // An existing SparkContext.
  2. val sqlContext = new org.apache.spark.sql.SQLContext(sc)
  3. // Create the DataFrame
  4. val df = sqlContext.read.json("examples/src/main/resources/people.json")
  5. // Show the content of the DataFrame
  6. df.show()
  7. // age name
  8. // null Michael
  9. // 30 Andy
  10. // 19 Justin
  11. // Print the schema in a tree format
  12. df.printSchema()
  13. // root
  14. // |-- age: long (nullable = true)
  15. // |-- name: string (nullable = true)
  16. // Select only the "name" column
  17. df.select("name").show()
  18. // name
  19. // Michael
  20. // Andy
  21. // Justin
  22. // Select everybody, but increment the age by 1
  23. df.select(df("name"), df("age") + 1).show()
  24. // name (age + 1)
  25. // Michael null
  26. // Andy 31
  27. // Justin 20
  28. // Select people older than 21
  29. df.filter(df("age") > 21).show()
  30. // age name
  31. // 30 Andy
  32. // Count people by age
  33. df.groupBy("age").count().show()
  34. // age count
  35. // null 1
  36. // 19 1
  37. // 30 1
  • Java
  1. JavaSparkContext sc // An existing SparkContext.
  2. SQLContext sqlContext = new org.apache.spark.sql.SQLContext(sc)
  3. // Create the DataFrame
  4. DataFrame df = sqlContext.read().json("examples/src/main/resources/people.json");
  5. // Show the content of the DataFrame
  6. df.show();
  7. // age name
  8. // null Michael
  9. // 30 Andy
  10. // 19 Justin
  11. // Print the schema in a tree format
  12. df.printSchema();
  13. // root
  14. // |-- age: long (nullable = true)
  15. // |-- name: string (nullable = true)
  16. // Select only the "name" column
  17. df.select("name").show();
  18. // name
  19. // Michael
  20. // Andy
  21. // Justin
  22. // Select everybody, but increment the age by 1
  23. df.select(df.col("name"), df.col("age").plus(1)).show();
  24. // name (age + 1)
  25. // Michael null
  26. // Andy 31
  27. // Justin 20
  28. // Select people older than 21
  29. df.filter(df.col("age").gt(21)).show();
  30. // age name
  31. // 30 Andy
  32. // Count people by age
  33. df.groupBy("age").count().show();
  34. // age count
  35. // null 1
  36. // 19 1
  37. // 30 1

详细的DataFrame API请参考 API Documentation

除了简单列引用和表达式,DataFrames还有丰富的library,功能包括string操作、date操作、常见数学操作等。详细内容请参考 DataFrame Function Reference

运行SQL查询程序(Running SQL Queries Programmatically)

Spark Application可以使用SQLContext的sql()方法执行SQL查询操作,sql()方法返回的查询结果为DataFrame格式。代码如下:

  • Scala
  1. val sqlContext = ... // An existing SQLContext
  2. val df = sqlContext.sql("SELECT * FROM table")
  • Java
  1. SQLContext sqlContext = ... // An existing SQLContext
  2. DataFrame df = sqlContext.sql("SELECT * FROM table")

DataFrames与RDDs的相互转换(Interoperating with RDDs)

Spark SQL支持两种RDDs转换为DataFrames的方式:

  • 使用反射获取RDD内的Schema

    • 当已知类的Schema的时候,使用这种基于反射的方法会让代码更加简洁而且效果也很好。
  • 通过编程接口指定Schema
    • 通过Spark SQL的接口创建RDD的Schema,这种方式会让代码比较冗长。
    • 这种方法的好处是,在运行时才知道数据的列以及列的类型的情况下,可以动态生成Schema

使用反射获取Schema(Inferring the Schema Using Reflection)

Spark SQL支持将JavaBean的RDD自动转换成DataFrame。通过反射获取Bean的基本信息,依据Bean的信息定义Schema。当前Spark SQL版本(Spark 1.5.2)不支持嵌套的JavaBeans和复杂数据类型(如:List、Array)。创建一个实现Serializable接口包含所有属性getters和setters的类来创建一个JavaBean。通过调用createDataFrame并提供JavaBean的Class object,指定一个Schema给一个RDD。示例如下:

  1. public static class Person implements Serializable {
  2. private String name;
  3. private int age;
  4. public String getName() {
  5. return name;
  6. }
  7. public void setName(String name) {
  8. this.name = name;
  9. }
  10. public int getAge() {
  11. return age;
  12. }
  13. public void setAge(int age) {
  14. this.age = age;
  15. }
  16. }
  1. // sc is an existing JavaSparkContext.
  2. SQLContext sqlContext = new org.apache.spark.sql.SQLContext(sc);
  3. // Load a text file and convert each line to a JavaBean.
  4. JavaRDD<Person> people = sc.textFile("examples/src/main/resources/people.txt").map(
  5. new Function<String, Person>() {
  6. public Person call(String line) throws Exception {
  7. String[] parts = line.split(",");
  8. Person person = new Person();
  9. person.setName(parts[0]);
  10. person.setAge(Integer.parseInt(parts[1].trim()));
  11. return person;
  12. }
  13. });
  14. // Apply a schema to an RDD of JavaBeans and register it as a table.
  15. DataFrame schemaPeople = sqlContext.createDataFrame(people, Person.class);
  16. schemaPeople.registerTempTable("people");
  17. // SQL can be run over RDDs that have been registered as tables.
  18. DataFrame teenagers = sqlContext.sql("SELECT name FROM people WHERE age >= 13 AND age <= 19")
  19. // The results of SQL queries are DataFrames and support all the normal RDD operations.
  20. // The columns of a row in the result can be accessed by ordinal.
  21. List<String> teenagerNames = teenagers.javaRDD().map(new Function<Row, String>() {
  22. public String call(Row row) {
  23. return "Name: " + row.getString(0);
  24. }
  25. }).collect();

通过编程接口指定Schema(Programmatically Specifying the Schema)

当JavaBean不能被预先定义的时候,编程创建DataFrame分为三步:

  • 从原来的RDD创建一个Row格式的RDD
  • 创建与RDD中Rows结构匹配的StructType,通过该StructType创建表示RDD的Schema
  • 通过SQLContext提供的createDataFrame方法创建DataFrame,方法参数为RDD的Schema

示例如下:

  1. import org.apache.spark.api.java.function.Function;
  2. // Import factory methods provided by DataTypes.
  3. import org.apache.spark.sql.types.DataTypes;
  4. // Import StructType and StructField
  5. import org.apache.spark.sql.types.StructType;
  6. import org.apache.spark.sql.types.StructField;
  7. // Import Row.
  8. import org.apache.spark.sql.Row;
  9. // Import RowFactory.
  10. import org.apache.spark.sql.RowFactory;
  11. // sc is an existing JavaSparkContext.
  12. SQLContext sqlContext = new org.apache.spark.sql.SQLContext(sc);
  13. // Load a text file and convert each line to a JavaBean.
  14. JavaRDD<String> people = sc.textFile("examples/src/main/resources/people.txt");
  15. // The schema is encoded in a string
  16. String schemaString = "name age";
  17. // Generate the schema based on the string of schema
  18. List<StructField> fields = new ArrayList<StructField>();
  19. for (String fieldName: schemaString.split(" ")) {
  20. fields.add(DataTypes.createStructField(fieldName, DataTypes.StringType, true));
  21. }
  22. StructType schema = DataTypes.createStructType(fields);
  23. // Convert records of the RDD (people) to Rows.
  24. JavaRDD<Row> rowRDD = people.map(
  25. new Function<String, Row>() {
  26. public Row call(String record) throws Exception {
  27. String[] fields = record.split(",");
  28. return RowFactory.create(fields[0], fields[1].trim());
  29. }
  30. });
  31. // Apply the schema to the RDD.
  32. DataFrame peopleDataFrame = sqlContext.createDataFrame(rowRDD, schema);
  33. // Register the DataFrame as a table.
  34. peopleDataFrame.registerTempTable("people");
  35. // SQL can be run over RDDs that have been registered as tables.
  36. DataFrame results = sqlContext.sql("SELECT name FROM people");
  37. // The results of SQL queries are DataFrames and support all the normal RDD operations.
  38. // The columns of a row in the result can be accessed by ordinal.
  39. List<String> names = results.javaRDD().map(new Function<Row, String>() {
  40. public String call(Row row) {
  41. return "Name: " + row.getString(0);
  42. }
  43. }).collect();
转载请注明出处:http://www.cnblogs.com/BYRans/

转】Spark SQL 之 DataFrame的更多相关文章

  1. Spark SQL 之 DataFrame

    Spark SQL 之 DataFrame 转载请注明出处:http://www.cnblogs.com/BYRans/ 概述(Overview) Spark SQL是Spark的一个组件,用于结构化 ...

  2. spark结构化数据处理:Spark SQL、DataFrame和Dataset

    本文讲解Spark的结构化数据处理,主要包括:Spark SQL.DataFrame.Dataset以及Spark SQL服务等相关内容.本文主要讲解Spark 1.6.x的结构化数据处理相关东东,但 ...

  3. Spark SQL、DataFrame和Dataset——转载

    转载自:  Spark SQL.DataFrame和Datase

  4. Spark官方1 ---------Spark SQL和DataFrame指南(1.5.0)

    概述 Spark SQL是用于结构化数据处理的Spark模块.它提供了一个称为DataFrames的编程抽象,也可以作为分布式SQL查询引擎. Spark SQL也可用于从现有的Hive安装中读取数据 ...

  5. Spark SQL and DataFrame Guide(1.4.1)——之DataFrames

    Spark SQL是处理结构化数据的Spark模块.它提供了DataFrames这样的编程抽象.同一时候也能够作为分布式SQL查询引擎使用. DataFrames DataFrame是一个带有列名的分 ...

  6. Spark学习之路(八)—— Spark SQL 之 DataFrame和Dataset

    一.Spark SQL简介 Spark SQL是Spark中的一个子模块,主要用于操作结构化数据.它具有以下特点: 能够将SQL查询与Spark程序无缝混合,允许您使用SQL或DataFrame AP ...

  7. Spark 系列(八)—— Spark SQL 之 DataFrame 和 Dataset

    一.Spark SQL简介 Spark SQL 是 Spark 中的一个子模块,主要用于操作结构化数据.它具有以下特点: 能够将 SQL 查询与 Spark 程序无缝混合,允许您使用 SQL 或 Da ...

  8. spark sql 创建DataFrame

    SQLContext是创建DataFrame和执行SQL语句的入口 通过RDD结合case class转换为DataFrame 1.准备:hdfs上提交一个文件,schema为id name age, ...

  9. Spark SQL 之 Data Sources

    #Spark SQL 之 Data Sources 转载请注明出处:http://www.cnblogs.com/BYRans/ 数据源(Data Source) Spark SQL的DataFram ...

随机推荐

  1. RxJava系列之中的一个 初识Rxjava

    1.简单介绍 基础知识 响应式代码的基本组成部分是Observables和Subscribers(事实上Observer才是最小的构建块,但实践中使用最多的是Subscriber.由于Subscrib ...

  2. ASP.NET MVC 学习笔记-2.Razor语法 ASP.NET MVC 学习笔记-1.ASP.NET MVC 基础 反射的具体应用 策略模式的具体应用 责任链模式的具体应用 ServiceStack.Redis订阅发布服务的调用 C#读取XML文件的基类实现

    ASP.NET MVC 学习笔记-2.Razor语法   1.         表达式 表达式必须跟在“@”符号之后, 2.         代码块 代码块必须位于“@{}”中,并且每行代码必须以“: ...

  3. windows下的两个等待函数

    windows下的两个等待技术 第一种: Win32  Sleep()函数      这个函数要求操作系统中止线程动作.直到读过某个指定的时间之后才恢复.能在某个线程结束时(而不是某段时间结束时)被调 ...

  4. Sublime Text 3.3143最新注册码

    Sublime Text3之前用的是老版本,昨天手贱点了更新,就要重新激活,网上找了好多都是之前版本的,以下给干货 —– BEGIN LICENSE —– TwitterInc User Licens ...

  5. 计算机体系结构的铁律(iron law)

    计算机体系结构的铁律可由下面公式来描写叙述: 从Programmer的角度来看,处理器的性能就是运行程序的耗费的时间.所以用Time/Program来刻画处理器性能.而这个简单的公式背后是有很丰富的内 ...

  6. sublime text 3 乱码

    sublime text 是一款很好用的文字编辑软件,可谓是程序员必备,但是最近发现在mac端使用的时候,中文乱码, 网上一些解决方案,抄袭严重,没有解决实际问题,所以记录下自己解决问题的过程. 1. ...

  7. 我要开启vue2新征程。

    最近我们Team接到一个新项目,给财务部开发一个内部用的结算系统. 我想了想,心里这个兴奋啊(内部系统诶,可以大胆一点的用vue2了...) 又多了一个能练手的项目,之前的卡爷就是太坑爹了...明明v ...

  8. scala wordcount kmeans

    scala wordcount   kmeans k-means算法的输入对象是d维向量空间的一些点,对一个d维向量的点集进行聚类. k-means聚类算法会将集合D划分成k个聚簇.

  9. diy数据库(二)--网络通信类

    一.首先,我们先实现OSS层的ossSocket类.供数据库client和数据库引擎进行通信 友情提示:相应上面的类图的头文件和源码附在了本文的最以下. int _fd ;//socket的文件描写叙 ...

  10. jeesite快速开发平台

    兴致勃勃地下载下来准备好好研究一番,安装启动结果报错啦: java.lang.ClassNotFoundException: com.thinkgem.jeesite.modules.sys.list ...