Dataframe Spark中数据帧、数据集和RDD之间的差异
我只是想知道Apache Spark中的Dataframe Spark中数据帧、数据集和RDD之间的差异,dataframe,apache-spark,apache-spark-sql,rdd,apache-spark-dataset,Dataframe,Apache Spark,Apache Spark Sql,Rdd,Apache Spark Dataset,我只是想知道Apache Spark中的RDD和DataFrame(Spark 2.0.0 DataFrame只是Dataset[Row]的类型别名)之间有什么区别 你能把一个转换成另一个吗?ADataFrame通过谷歌搜索“DataFrame definition”定义得很好: 数据帧是一个表或二维数组状结构 每列包含一个变量的测量值,每行 包含一个案例 因此,DataFrame由于其表格格式,具有额外的元数据,这允许Spark对最终确定的查询运行某些优化 另一方面,RDD,仅仅是一个Resl
RDD
和DataFrame
(Spark 2.0.0 DataFrame只是Dataset[Row]
的类型别名)之间有什么区别
你能把一个转换成另一个吗?A
DataFrame
通过谷歌搜索“DataFrame definition”定义得很好:
数据帧是一个表或二维数组状结构
每列包含一个变量的测量值,每行
包含一个案例
因此,DataFrame
由于其表格格式,具有额外的元数据,这允许Spark对最终确定的查询运行某些优化
另一方面,RDD
,仅仅是一个ReslientD分布的D数据集,它更像是一个无法优化的数据黑盒,因为可以对其执行的操作没有那么受约束
但是,您可以通过其RDD
方法从数据帧转到RDD
,也可以通过toDF
方法从RDD
转到DataFrame
(如果RDD是表格格式)
一般而言由于内置查询优化,建议尽可能使用
数据框
。数据框相当于RDBMS中的表,也可以类似于RDDs中的“本机”分布式集合的方式进行操作。与RDD不同,数据帧跟踪模式并支持各种关系操作,从而实现更优化的执行。
每个DataFrame对象表示一个逻辑计划,但由于其“惰性”性质,在用户调用特定的“输出操作”之前不会执行任何操作。简单地说,
RDD
是核心组件,而DataFrame
是spark 1.30中引入的API
RDD
名为RDD
的数据分区集合。这些RDD
必须遵循以下几个属性:
- 一成不变
- 容错
- 分发
- 更多
RDD
可以是结构化的,也可以是非结构化的
数据帧
DataFrame
是Scala、Java、Python和R中可用的API。它允许处理任何类型的结构化和半结构化数据。要定义DataFrame
,将分布式数据集合组织到名为DataFrame
的命名列中。您可以在DataFrame
中轻松优化rdd
。
您可以使用DataFrame
一次处理JSON数据、拼花地板数据和HiveQL数据
val sampleRDD = sqlContext.jsonFile("hdfs://localhost:9000/jsondata.json")
val sample_DF = sampleRDD.toDF()
这里SAMPAREDF考虑为<代码>数据文件< /代码>。code>sampleRDD被称为
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
,你得到的是一个需要操作的列
对象。在具有丰富类型系统(如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
是从SchemaRDD
演变而来的
是的。。Dataframe
和RDD
之间的转换是完全可能的
下面是一些示例代码片段
isdf.rdd
rdd[Row]
- 1)
转换为yourrddOffrow.toDF
DataFrame
val sampleRDD = sqlContext.jsonFile("hdfs://localhost:9000/jsondata.json")
val sample_DF = sampleRDD.toDF()
createDataFrame
val df=spark.createDataFrame(rddOfRow,schema)
来自scala案例类和scala反射api
import org.apache.spark.sql.catalyst.ScalaReflection
val schema = ScalaReflection.schemaFor[YourScalacaseClass].dataType.asInstanceOf[StructType]
或使用编码器
import org.apache.spark.sql.Encoders
val mySchema = Encoders.product[MyCaseClass].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
(弹性分布式数据集)API自发布以来一直处于活跃状态
1.0版本
RDD
API提供了许多转换方法,例如map
(),
filter
()和reduce
()用于对数据执行计算。每个
在这些方法中,有一个新的RDD
表示转换后的
数据。但是,这些方法只是定义要执行的操作
已执行,并且在执行操作之前不会执行转换
方法被调用。动作方法的示例有收集()和
saveAsObjectFile
()
RDD示例:
rdd.filter(_.age > 21) // transformation
.map(_.last)// transformation
.saveAsObjectFile("under21.bin") // action
dataset.filter(_.age < 21);
示例:使用RDD按属性筛选
rdd.filter(_.age > 21)
DataFrame
API
Spark 1.3作为项目的一部分,引入了一个新的DataFrame
API
钨倡议,旨在提高性能和
Spark的可伸缩性。DataFrame
API引入了
模式来描述数据,允许Spark管理模式和
只在节点之间传递数据,比使用
Java序列化
DataFrame
API与RDD
API完全不同,因为它
是A吗
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]
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()
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|
+------+----+----+
val rowsRdd: RDD[Row] = df.rdd() // DataFrame to RDD