Answers:
一个DataFrame
很好的定义与谷歌搜索“ DataFrame定义”:
数据框是表或二维数组状结构,其中每一列包含一个变量的度量,每一行包含一个个案。
因此,DataFrame
由于其表格格式,因此具有附加的元数据,这使Spark可以在最终查询中运行某些优化。
的RDD
,另一方面,仅仅是- [R esilient d istributed d ataset是更不能作为可以针对它要执行的操作进行优化的数据的黑盒的,不作为限制。
但是,你可以从一个数据帧到一个RDD
通过它的rdd
方法,你可以从一个去RDD
到DataFrame
(如果RDD是表格形式),通过该toDF
方法
通常,DataFrame
由于内置的查询优化功能,建议尽可能使用。
第一件事是
DataFrame
从演变而来的SchemaRDD
。
是的。Dataframe
和之间的转换RDD
是绝对可能的。
以下是一些示例代码片段。
df.rdd
是 RDD[Row]
以下是一些用于创建数据框的选项。
1)yourrddOffrow.toDF
转换为DataFrame
。
2)使用createDataFrame
SQL上下文
val df = spark.createDataFrame(rddOfRow, schema)
模式可以来自不错的SO post所描述的以下某些选项。.
来自scala case类和scala反射apiimport org.apache.spark.sql.catalyst.ScalaReflection val schema = ScalaReflection.schemaFor[YourScalacaseClass].dataType.asInstanceOf[StructType]
或使用
Encoders
import org.apache.spark.sql.Encoders val mySchema = Encoders.product[MyCaseClass].schema
如Schema所述,也可以使用
StructType
和 创建StructField
val schema = new StructType() .add(StructField("id", StringType, true)) .add(StructField("col1", DoubleType, true)) .add(StructField("col2", DoubleType, true)) etc...
RDD
API:的
RDD
,因为1.0版本(弹性分布式数据集)API已在火花。所述
RDD
API提供了许多转化方法,例如map
(),filter
(),和reduce
(),用于对数据执行计算。这些方法中的每一个都会产生一个新的RDD
代表转换后的数据。但是,这些方法只是定义要执行的操作,并且只有在调用action方法之后才执行转换。动作方法的示例是collect
()和saveAsObjectFile
()。
RDD示例:
rdd.filter(_.age > 21) // transformation
.map(_.last)// transformation
.saveAsObjectFile("under21.bin") // action
示例:使用RDD按属性过滤
rdd.filter(_.age > 21)
DataFrame
API
DataFrame
作为Tungsten计划的一部分,Spark 1.3引入了新的API,该API旨在改善Spark的性能和可伸缩性。该DataFrame
API引入了模式的概念来描述数据,使星火管理模式和唯一的节点之间传递数据,比使用Java序列化一个更有效的方式。该
DataFrame
API与该RDD
API 完全不同,因为它是用于构建关系查询计划的API,Spark的Catalyst优化器随后可以执行该查询计划。对于熟悉构建查询计划的开发人员来说,API是很自然的
示例SQL风格:
df.filter("age > 21");
限制: 由于代码按名称引用数据属性,因此编译器不可能捕获任何错误。如果属性名称不正确,则仅在创建查询计划时才在运行时检测到错误。
该DataFrame
API的另一个缺点是,它以Scala为中心,虽然它确实支持Java,但支持有限。
例如,当DataFrame
从现有RDD
的Java对象创建时,Spark的Catalyst优化器无法推断模式,并假定DataFrame中的任何对象都实现了该scala.Product
接口。Scala case class
解决了问题,因为他们实现了此接口。
Dataset
API该
Dataset
API在Spark 1.6中作为API预览发布,旨在提供两全其美的方法。RDD
API 熟悉的面向对象的编程风格和编译时类型安全性,但具有Catalyst查询优化器的性能优势。数据集还使用与DataFrame
API 相同的高效堆外存储机制 。在序列化数据时,
Dataset
API具有编码器的概念, 可以在JVM表示(对象)和Spark的内部二进制格式之间进行转换。Spark具有内置的编码器,这些编码器非常先进,它们生成字节码以与堆外数据进行交互,并提供按需访问单个属性的功能,而不必对整个对象进行反序列化。Spark尚未提供用于实现自定义编码器的API,但已计划在将来的版本中使用。此外,该
Dataset
API旨在与Java和Scala均能很好地协同工作。使用Java对象时,重要的是它们必须与Bean完全兼容。
Dataset
API SQL样式示例:
dataset.filter(_.age < 21);
加泰罗尼亚级的流量。。(Spark Summit揭秘DataFrame和Dataset演示)
进一步阅读... databricks 文章-三种Apache Spark API的故事:RDD与DataFrames和Datasets
df.filter("age > 21");
,只能在运行时对其进行评估/分析。自其字符串。如果是数据集,则数据集符合Bean的要求。所以年龄是豆子的财产。如果bean中不存在age属性,那么您将在ie编译时就早知道了dataset.filter(_.age < 21);
。分析错误可以重命名为评估错误。
Apache Spark提供三种类型的API
这是RDD,Dataframe和Dataset之间的API比较。
Spark提供的主要抽象是弹性分布式数据集(RDD),它是跨集群节点划分的元素的集合,可以并行操作。
分布式集合:
RDD使用MapReduce操作,该操作被广泛用于在集群上使用并行分布式算法处理和生成大型数据集。它允许用户使用一组高级运算符来编写并行计算,而不必担心工作分配和容错性。
不变的: RDD由分区的记录集合组成。分区是RDD中并行性的基本单位,每个分区是数据的一个逻辑分区,它是不可变的,并且是通过对现有分区进行一些转换而创建的。不可变性有助于实现计算的一致性。
容错: 如果我们丢失了RDD的某些分区,则可以按世系在该分区上重播转换以实现相同的计算,而不是跨多个节点进行数据复制。此特性是RDD的最大优点,因为它可以节省数据管理和复制方面的大量努力,从而实现了更快的计算。
惰性评估: Spark中的所有转换都是惰性的,因为它们不会立即计算出结果。相反,他们只记得应用于某些基本数据集的转换。仅当操作要求将结果返回给驱动程序时才计算转换。
功能转换: RDD支持两种类型的操作:转换(从现有操作创建新数据集)和动作(在数据集上运行计算后将值返回到驱动程序)。
数据处理格式:
它可以轻松有效地处理结构化数据和非结构化数据。
支持的编程语言:
RDD API 支持 Java,Scala,Python和R。
没有内置的优化引擎: 使用结构化数据时,RDD无法利用Spark的高级优化器(包括催化剂优化器和Tungsten执行引擎)的优势。开发人员需要根据其属性优化每个RDD。
处理结构化数据: 与数据框和数据集不同,RDD不会推断已摄取数据的模式,而是需要用户指定它。
Spark在Spark 1.3版本中引入了数据帧。数据框克服了RDD所面临的主要挑战。
DataFrame是组织为命名列的分布式数据集合。从概念上讲,它等效于关系数据库或R / Python数据框中的表。与Dataframe一起,Spark还引入了催化剂优化器,它利用高级编程功能来构建可扩展的查询优化器。
行对象的分布式集合: DataFrame是组织为命名列的数据的分布式集合。它在概念上等效于关系数据库中的表,但是在后台进行了更丰富的优化。
数据处理: 处理结构化和非结构化数据格式(Avro,CSV,弹性搜索和Cassandra)和存储系统(HDFS,HIVE表,MySQL等)。它可以从所有这些各种数据源读取和写入。
使用催化剂优化器进行优化: 它支持SQL查询和DataFrame API。数据框分四个阶段使用催化剂树转换框架,
1.Analyzing a logical plan to resolve references
2.Logical plan optimization
3.Physical planning
4.Code generation to compile parts of the query to Java bytecode.
Hive兼容性: 使用Spark SQL,您可以在现有Hive仓库上运行未修改的Hive查询。它重用了Hive前端和MetaStore,并为您提供了与现有Hive数据,查询和UDF的完全兼容性。
Tungsten: Tungsten提供了一个物理执行后端,该后端可以显式管理内存并动态生成字节码以进行表达式求值。
支持的编程语言:
Dataframe API 支持 Java,Scala,Python和R。
例:
case class Person(name : String , age : Int)
val dataframe = sqlContext.read.json("people.json")
dataframe.filter("salary > 10000").show
=> throws Exception : cannot resolve 'salary' given input age , name
当您使用多个转换和聚合步骤时,这尤其具有挑战性。
例:
case class Person(name : String , age : Int)
val personRDD = sc.makeRDD(Seq(Person("A",10),Person("B",20)))
val personDF = sqlContext.createDataframe(personRDD)
personDF.rdd // returns RDD[Row] , does not returns RDD[Person]
数据集API是DataFrames的扩展,它提供了类型安全的,面向对象的编程接口。它是映射到关系模式的对象的强类型,不可变的集合。
API是数据集的核心,是一个称为编码器的新概念,它负责在JVM对象和表格表示形式之间进行转换。该表格表示形式使用Spark内部钨二进制格式存储,从而允许对序列化数据进行操作并提高内存利用率。Spark 1.6支持自动生成多种类型的编码器,包括原始类型(例如String,Integer,Long),Scala案例类和Java Bean。
同时提供RDD和Dataframe的优点: RDD(功能编程,类型安全),DataFrame(关系模型,查询优化,钨执行,排序和混排)
编码器: 通过使用编码器,可以轻松地将任何JVM对象转换为数据集,从而允许用户与数据帧不同地使用结构化和非结构化数据。
支持的编程语言: Datasets API当前仅在Scala和Java中可用。当前在1.6版中不支持Python和R。Python支持版本2.0。
类型安全性: Datasets API提供了编译时安全性,这在Dataframes中是不可用的。在下面的示例中,我们可以看到数据集如何通过编译lambda函数对域对象进行操作。
例:
case class Person(name : String , age : Int)
val personRDD = sc.makeRDD(Seq(Person("A",10),Person("B",20)))
val personDF = sqlContext.createDataframe(personRDD)
val ds:Dataset[Person] = personDF.as[Person]
ds.filter(p => p.age > 25)
ds.filter(p => p.salary > 25)
// error : value salary is not a member of person
ds.rdd // returns RDD[Person]
例:
ds.select(col("name").as[String], $"age".as[Int]).collect()
不支持Python和R:从1.6版开始,数据集仅支持Scala和Java。将在Spark 2.0中引入Python支持。
与现有的RDD和Dataframe API相比,Datasets API具有更好的类型安全性和功能性编程带来的多个优势。由于API中对类型强制转换要求的挑战,您仍然不是必需的类型安全性,并且会使代码变脆。
Dataset
不是LINQ,lambda表达式不能解释为表达式树。因此,存在黑匣子,您几乎失去了所有(如果不是全部)优化器收益。可能缺点的一小部分:Spark 2.0数据集与DataFrame。另外,只是重复我多次声明的内容-通常,Dataset
API 无法进行端到端类型检查。联接只是最突出的例子。
RDD
RDD
是可以并行操作的元素的容错集合。
DataFrame
DataFrame
是按命名列组织的数据集。从概念上讲,它等效于关系数据库中的表或R / Python中的数据框,但在底层具有更丰富的优化。
Dataset
Dataset
是数据的分布式集合。数据集是Spark 1.6中添加的新接口,它具有RDD的优点 (强类型输入,使用强大的lambda函数的能力)以及Spark SQL的优化执行引擎的 优点。
注意:
Dataset[Row]
Scala / Java中的行数据集()通常称为DataFrames。
Nice comparison of all of them with a code snippet.
问:能否将RDD转换为DataFrame或将RDD转换为DataFrame?
1。 RDD
要DataFrame
与.toDF()
val rowsRdd: RDD[Row] = sc.parallelize(
Seq(
Row("first", 2.0, 7.0),
Row("second", 3.5, 2.5),
Row("third", 7.0, 5.9)
)
)
val df = spark.createDataFrame(rowsRdd).toDF("id", "val1", "val2")
df.show()
+------+----+----+
| id|val1|val2|
+------+----+----+
| first| 2.0| 7.0|
|second| 3.5| 2.5|
| third| 7.0| 5.9|
+------+----+----+
更多方法:在Spark中将RDD对象转换为Dataframe
2. DataFrame
/ DataSet
到RDD
with .rdd()
方法
val rowsRdd: RDD[Row] = df.rdd() // DataFrame to RDD
因为它DataFrame
是弱类型的,开发人员没有从类型系统中获得好处。例如,假设您要从SQL读取某些内容并对其进行一些聚合:
val people = sqlContext.read.parquet("...")
val department = sqlContext.read.parquet("...")
people.filter("age > 30")
.join(department, people("deptId") === department("id"))
.groupBy(department("name"), "gender")
.agg(avg(people("salary")), max(people("age")))
当你说people("deptId")
,你没有回头看看Int
,或者Long
,你要回Column
需要对其进行操作对象。在具有丰富类型系统的语言(例如Scala)中,您最终会失去所有类型安全性,从而增加了在编译时可能发现的事物的运行时错误数量。
相反,DataSet[T]
是打字。当您这样做时:
val people: People = val people = sqlContext.read.parquet("...").as[People]
您实际上是在找回一个People
对象,该对象deptId
是实际的整数类型而不是列类型,因此可以利用类型系统。
从Spark 2.0开始,DataFrame和DataSet API将统一,其中DataFrame
将是的类型别名DataSet[Row]
。
DataFrame
是避免破坏API更改。无论如何,只是想指出这一点。感谢您的编辑和支持。
Simply RDD
是核心组件,但是DataFrame
spark 1.30中引入的API。
称为的数据分区的集合RDD
。这些RDD
必须遵循一些属性,例如:
这RDD
是结构化的或非结构化的。
DataFrame
是Scala,Java,Python和R中可用的API。它允许处理任何类型的结构化和半结构化数据。首先,定义DataFrame
为称为的命名列的分布式数据集合DataFrame
。您可以轻松地优化RDDs
中的DataFrame
。您可以使用来一次处理JSON数据,镶木地板数据,HiveQL数据DataFrame
。
val sampleRDD = sqlContext.jsonFile("hdfs://localhost:9000/jsondata.json")
val sample_DF = sampleRDD.toDF()
这里Sample_DF认为是DataFrame
。sampleRDD
(原始数据)称为RDD
。
大多数答案都是正确的,只想在这里加一点
在Spark 2.0中,两个API(DataFrame + DataSet)将被统一为一个API。
“统一数据框架和数据集:在Scala和Java中,数据框架和数据集已经统一,即数据框架只是Row数据集的类型别名。在Python和R中,由于缺乏类型安全性,数据框架是主要的编程接口。”
数据集与RDD相似,但是,它们不使用Java序列化或Kryo,而是使用专用的Encoder对对象进行序列化以进行网络处理或传输。
Spark SQL支持两种将现有RDD转换为数据集的方法。第一种方法使用反射来推断包含特定对象类型的RDD的架构。这种基于反射的方法可以使代码更简洁,当您在编写Spark应用程序时已经了解架构时,可以很好地工作。
创建数据集的第二种方法是通过编程界面,该界面允许您构造模式,然后将其应用于现有的RDD。尽管此方法较为冗长,但可以在运行时才知道列及其类型的情况下构造数据集。
在这里您可以找到RDD tof数据框对话答案
希望对您有所帮助!
Spark RDD (resilient distributed dataset)
:
RDD是核心数据抽象API,自Spark的第一个发行版(Spark 1.0)起可用。它是用于处理分布式数据收集的较低级别的API。RDD API公开了一些非常有用的方法,这些方法可用于对底层物理数据结构进行非常严格的控制。它是分布在不同计算机上的分区数据的不可变(只读)集合。RDD支持在大型群集上进行内存中计算,从而以容错方式加快大数据处理速度。为了实现容错,RDD使用DAG(有向无环图),它由一组顶点和边组成。DAG中的顶点和边缘分别表示RDD和要在该RDD上应用的操作。在RDD上定义的转换是惰性的,仅在调用操作时执行
Spark DataFrame
:
Spark 1.3引入了两个新的数据抽象API – DataFrame和DataSet。DataFrame API将数据组织到命名列中,例如关系数据库中的表。它使程序员能够在分布式数据集合上定义架构。DataFrame中的每一行都是对象类型行。与SQL表一样,每一列在DataFrame中必须具有相同数量的行。简而言之,DataFrame是延迟评估的计划,该计划指定需要对数据的分布式集合执行的操作。DataFrame也是一个不可变的集合。
Spark DataSet
:
作为对DataFrame API的扩展,Spark 1.3还引入了DataSet API,该API在Spark中提供了严格类型化和面向对象的编程接口。它是不可变的,类型安全的分布式数据集合。与DataFrame一样,DataSet API也使用Catalyst引擎来启用执行优化。DataSet是DataFrame API的扩展。
Other Differences
--
一个数据帧是有模式的RDD。您可以将其视为关系数据库表,因为每一列都有一个名称和一个已知类型。DataFrames的强大功能来自以下事实:当您从结构化数据集(Json,Parquet ..)创建DataFrame时,Spark可以通过传递整个(Json,Parquet ..)数据集来推断模式。正在加载。然后,在计算执行计划时,Spark可以使用该架构并进行更好的计算优化。请注意,Spark v1.3.0之前将DataFrame称为SchemaRDD
Spark RDD –
RDD代表弹性分布式数据集。它是记录的只读分区集合。RDD是Spark的基本数据结构。它允许程序员以容错的方式在大型群集上执行内存中计算。因此,加快了任务。
Spark数据框 –
与RDD不同,数据组织为命名列。例如,关系数据库中的表。它是不可变的分布式数据集合。Spark中的DataFrame允许开发人员将结构强加到分布式数据集合上,从而实现更高级别的抽象。
Spark数据集 –
Apache Spark中的数据集是DataFrame API的扩展,它提供了类型安全的,面向对象的编程接口。数据集通过将表达式和数据字段公开给查询计划者,从而利用了Spark的Catalyst优化器。
所有不错的答案,并且使用每个API都有一定的取舍。数据集被构建为超级API,可以解决很多问题,但是如果您了解自己的数据,并且如果处理算法经过优化可以在单次传递到大型数据中完成很多事情,那么RDD在许多情况下仍然效果最佳。RDD似乎是最佳选择。
使用数据集API进行聚合仍会消耗内存,并且随着时间的推移会变得更好。