2016-05-03 85 views
7

Spark documentation顯示瞭如何使用Scala案例類來推斷架構,從RDD創建DataFrame。我試圖用sqlContext.createDataFrame(RDD, CaseClass)來重現這個概念,但是我的DataFrame結果是空的。這裏是我的Scala代碼:如何將基於案例類的RDD轉換爲DataFrame?

// 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) 
++ 
|| 
++ 
|| 
|| 
++ 

我缺少什麼?

謝謝!

回答

12

所有你需要的僅僅是

val dogDF = sqlContext.createDataFrame(dogRDD) 

第二個參數是Java的API的一部分,並希望你的類遵循Java Bean約定(getter/setter方法)。您的案例類不遵循此約定,因此沒有檢測到屬性,導致沒有列的空DataFrame。

+1

這個工作。我還必須將case類的定義移到主函數之外,以避免出現'error:No TypeTag for Dog''。謝謝! – sparkour

+0

我明白了,非常有趣,所以第二個參數只有在從Java API調用時才需要,scala會自動檢測應該轉換爲列的Type字段? – qwwqwwq

5

您可以使用toDF如下例類實例的Seq直接創建DataFrame

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

案例類方法不能在集羣模式下運行。它會給你定義的案例類別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()不會工作要麼

相關問題