2016-05-03 16 views
7

W dokumencie Spark documentation pokazano, jak utworzyć obiekt DataFrame z RDD, używając klas przypadków Scala do wyprowadzania schematu. Próbuję odtworzyć tę koncepcję za pomocą sqlContext.createDataFrame(RDD, CaseClass), ale moje DataFrame kończy się pusty. Oto mój kod Scala:Jak przekonwertować RDD z klasy na klasy do 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() 

Wyjście widzę to:

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

Czego mi brakuje?

Dzięki!

Odpowiedz

12

Wszystko czego potrzebujesz to tylko

val dogDF = sqlContext.createDataFrame(dogRDD) 

Drugi parametr jest częścią Java API i oczekuje, że klasa następująco Java Beans Konwencji (pobierające/ustawiające). Twoja klasa sprawy nie jest zgodna z tą konwencją, więc nie wykryto żadnej właściwości, która prowadzi do pustej ramki DataFrame bez kolumn.

+1

działało to. Musiałem również przenieść definicję klasy case poza moją główną funkcją, aby uniknąć 'error: No TypeTag available for Dog'. Dzięki! – sparkour

+0

Widzę, bardzo interesujące, więc drugi parametr jest wymagany tylko podczas wywoływania z Java API, scala po prostu automagicznie wykryje pola Typu, który powinien zostać przekonwertowany na kolumny? – qwwqwwq

5

Można utworzyć DataFrame bezpośrednio z Seq instancji klasy przypadku użycia toDF następująco:

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

Case Class podejście nie będzie działać w trybie klastra. Da to ClassNotFoundException zdefiniowanej klasie przypadku.

przekonwertować go do RDD[Row] i zdefiniować schemat swoimi RDD z StructField a następnie createDataFrame jak

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() przyzwyczajenie praca albo

Powiązane problemy