Spark文档展示了如何从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的一部分,希望您的类遵循javabean约定(getters/setters)。您的case类不遵循此约定,因此未检测到任何属性,从而导致没有列的空DataFrame。
您可以使用toDF
直接从事例类实例的Seq
创建DataFrame
,如下所示:
val dogDf = Seq(Dog("Rex"), Dog("Fido")).toDF
案例类方法在集群模式下不起作用。它将为您定义的case类提供ClassNotFoundException
。
将其转换为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()
在中都不起作用