2017-04-12 32 views
2

据我所知,可以使用rdd.toDS将RDD转换为数据集。但是也存在rdd.toDF。其中一个真的有什么好处吗?Spark's toDS vs DF

在玩了一天的Dataset API之后,我发现几乎所有的操作都把我带到一个DataFrame中(例如withColumn)。在使用toDS转换RDD后,我经常发现需要另一次转换为DataSet,因为某些事情再次将我带入DataFrame。

我错误地使用了API吗?我是否应该坚持使用.toDF,并且只能在操作链末尾转换为DataSet?或者之前使用toDS有什么好处?

这里是一个小具体例子

spark 
    .read 
    .schema (...) 
    .json (...) 
    .rdd 
    .zipWithUniqueId 
    .map[(Integer,String,Double)] { case (row,id) => ... } 
    .toDS // now with a Dataset API (should use toDF here?) 
    .withColumnRenamed ("_1", "id") // now back to a DataFrame, not type safe :(
    .withColumnRenamed ("_2", "text") 
    .withColumnRenamed ("_2", "overall") 
    .as[ParsedReview] // back to a Dataset 
+1

据帧仅仅是'''数据集'''一个别名 - Databricks有对于一些内容数据集/数据帧的:https://docs.databricks.com/spark/latest/dataframes-datasets/index.html 另外agildata有一个在这里的语法快速入门:http://www.agildata.com/apache-spark-rdd-vs-dataframe-vs-dataset/ 我建议避免在两者之间尽可能转换。如果你满足于DataFrame的,使用它们,但如果你可以摆动它,数据集通常可以更优化。实际上,使用类型数据集代替DataFrame是很好的。 – Garren

+0

感谢您的评论和指针。我意识到这只是一个别名。我讨厌Dataframe api的无类型性质。大多数错误都是在运行时报告的,这对于仅仅学习框架的人来说是一个真正的痛苦。是否有关于如何留在多态数据集中的指导原则? (这样我就不必像上面的例子那样松动和恢复类型了) –

+0

你应该能够创建一个'''数据集'',只指定一些值,然后修改这些值通过使用setter调用对象的'''map'''。你给的例子对我来说不太清楚,因为它可能对你有用。使用像withColumnRenamed这样的便捷方法意味着为了简化动态列重命名而牺牲数据集的类型安全性。值得考虑的一件事是使用''''row.getString(row.fieldIndex(“column_name”))'''语法,这将为您提供与数据集值相关的安全性/ DataFrame值。 – Garren

回答

3

迈克尔Armburst很好地解释,转移到数据集和数据帧,以及两者之间的差异。基本上在spark 2.x中,他们将数据集和数据帧API集成到一个略有差别的API中。 “DataFrame只是泛型行对象的数据集,当你不知道所有的字段时,DF就是答案”。 https://www.youtube.com/watch?v=1a4pgYzeFwE

+0

感谢您的回答。我的问题(我应该更清楚)更多的是对数据集API的不满。我似乎无法做大量的工作,而不去掉类型不安全的DataFrames(偶尔我也需要放到RDD中,但这很好,因为它们是类型安全的)。 –