我试图理解数据集和数据框之间的区别,并发现以下有用的链接,但我无法理解类型安全的含义是什么?
Difference between DataFrame (in Spark 2.0 i.e DataSet[Row] ) and RDD in Spark
答案 0 :(得分:4)
RDD和数据集是类型安全的,这意味着编译器知道Columns以及Column的数据类型是否为Long,String等。
但是,在Dataframe中,每当您调用一个动作(例如collect()
)时,它将以行数组而不是长字符串数据类型返回结果。在数据框中,列具有自己的类型,例如整数,字符串,但它们不会向您公开。对您来说,任何类型。
要将数据行转换为合适的类型,必须使用.asInstanceOf
方法。
例如:在Scala中:
scala > :type df.collect()
Array[org.apache.spark.sql.Row]
df.collect().map{ row =>
val str = row(0).asInstanceOf[String]
val num = row(1).asInstanceOf[Long]
}
答案 1 :(得分:1)
类型安全是Spark 2.0中的高级API。
我们需要此API对数据集中的行执行更复杂的操作。
例如:
departments.joinWith(people, departments("id") === people("deptId"), "left_outer").show
答案 2 :(得分:1)
喜欢榜样的人,这里是:
case class Employ(name: String, age: Int, id: Int, department: String)
val empData = Seq(Employ("A", 24, 132, "HR"), Employ("B", 26, 131, "Engineering"), Employ("C", 25, 135, "Data Science"))
创建数据框和数据集数据
val empRDD = spark.sparkContext.makeRDD(empData)
val empDataFrame = empRDD.toDf()
val empDataset = empRDD.toDS()
让我们执行操作:
数据集
val empDatasetResult = empDataset.filter(employ => employ.age > 24)
数据框
val empDatasetResult = empDataframe.filter(employ => employ.age > 24)
//并引发错误“值年龄不是org.apache.spark.sql.Row对象的成员。”
对于Dataframe,当我们执行lambda时,它将返回Row对象而不是Integer对象,因此您不能直接执行employ.age > 24
,但是可以执行以下操作:
val empDataFrameResult = empDataFrame.filter(employ => employ.getAs[Int]("age") > 24)
为什么数据集如此特殊?
谁不喜欢样板代码?让我们使用数据集来创建它。.
感谢:https://blog.knoldus.com/spark-type-safety-in-dataset-vs-dataframe/