如何将基于 case-class 的 RDD 转换为 DataFrame?

How to convert a case-class-based RDD into a DataFrame?

Spark documentation 展示了如何从 RDD 创建 DataFrame,使用 Scala 案例 类 来推断模式。我正在尝试使用 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)
++
||
++
||
||
++

我错过了什么?

谢谢!

你只需要

val dogDF = sqlContext.createDataFrame(dogRDD)

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

您可以使用 toDFSeq 个案例 class 实例直接创建 DataFrame,如下所示:

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

案例Class 方法在集群模式下不起作用。它将 ClassNotFoundException 分配给您定义的案例 class。

将其转换为 RDD[Row] 并使用 StructField 定义 RDD 的架构,然后 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() 也不行