如何将基于案例类的RDD转换为DataFrame?

时间:2016-05-03 12:36:29

标签: scala apache-spark dataframe apache-spark-sql rdd

Spark documentation显示如何使用Scala案例类推断架构,从RDD创建DataFrame。我正在尝试使用sqlContext.createDataFrame(RDD, CaseClass)重现此概念,但我的DataFrame最终为空。这是我的Scala代码:

// sc is the SparkContext, while sqlContext is the SQLContext.

// Define the case class and raw data
case class Dog(name: String)
val data = Array(
    Dog("Rex"),
    Dog("Fido")
)

// Create an RDD from the raw data
val dogRDD = sc.parallelize(data)

// Print the RDD for debugging (this works, shows 2 dogs)
dogRDD.collect().foreach(println)

// Create a DataFrame from the RDD
val dogDF = sqlContext.createDataFrame(dogRDD, classOf[Dog])

// Print the DataFrame for debugging (this fails, shows 0 dogs)
dogDF.show()

我看到的输出是:

Dog(Rex)
Dog(Fido)
++
||
++
||
||
++

我错过了什么?

谢谢!

3 个答案:

答案 0 :(得分:16)

您只需要

val dogDF = sqlContext.createDataFrame(dogRDD)

第二个参数是Java API的一部分,期望您的类遵循java bean约定(getters / setters)。您的案例类不遵循此约定,因此未检测到任何属性,这会导致没有列的空DataFrame。

答案 1 :(得分:6)

您可以使用DataFrame直接从Seq个案例类实例创建toDF,如下所示:

val dogDf = Seq(Dog("Rex"), Dog("Fido")).toDF

答案 2 :(得分:0)

案例类方法在群集模式下不起作用。它会为您定义的案例类提供ClassNotFoundException

将其转换为RDD[Row]并定义RDD的架构StructField,然后createDataFrame

val rdd = data.map { attrs => Row(attrs(0),attrs(1)) }  

val rddStruct = new StructType(Array(StructField("id", StringType, nullable = true),StructField("pos", StringType, nullable = true)))

sqlContext.createDataFrame(rdd,rddStruct)

toDF()无法正常工作