2016-05-03 40 views
7

Dönüştürme RDD'leri DataFrames'e dönüştürmek ve tekrar kullanmaktayım. İlk olarak, dataPair olarak adlandırılan bir tür RD (Int, Int) vardı. Sonra sütun başlıkları kullanılarak bir DataFrame nesnesi oluşturuldu: türü org.apache.spark bir RDD dönerBir RDD [Satır] geri DataFrame'e nasıl dönüştürülür

val testRDD = dataFrame.rdd 

:

val dataFrame = dataPair.toDF(header(0), header(1)) 

Sonra kullanılarak geri bir RDD bir DataFrame onu dönüştürülür. sql.Row (değil (Int, Int)). Sonra .toDF kullanarak bir RDD geri dönüştürmek istiyorum ama bir hata alıyorum:

error: value toDF is not a member of org.apache.spark.rdd.RDD[org.apache.spark.sql.Row] 

ben tip Verilerinin (Orta, Orta) testRDD için bir Şeması tanımlayan denedim ama türünü olsun uyumsuzluğu istisnalar:

: zaten Rows bir RDD bir DataFrame oluşturmak için
import sqlContext.implicits._ 

cevap

13

ithal ettik

error: type mismatch; 
found : org.apache.spark.rdd.RDD[org.apache.spark.sql.Row] 
required: org.apache.spark.rdd.RDD[Data] 
    val testRDD: RDD[Data] = dataFrame.rdd 
            ^

, genellikle iki ana seçenek var

1) 'u kullanarak import sqlContext.implicits._ numaralı telefonu alabilirsiniz. Ancak, bu yaklaşım sadece RDDs aşağıdaki türleri için kullanılabilir:

  • RDD[Int]
  • RDD[Long]
  • RDD[String]
  • RDD[T <: scala.Product]

(kaynak: SQLContext.implicits nesnenin Scaladoc)

The las t imzası aslında bir RDD dizisi veya vaka sınıflarının RDD'si için çalışabileceği anlamına gelir (çünkü tupeler ve vaka sınıfları scala.Product alt sınıflarıdır).

RDD[Row] için bu yaklaşımı kullanmak için, RDD[T <: scala.Product] ile eşleştirmeniz gerekir. Bu aşağıdaki kod snippet'lerinde gibi özel bir durum sınıfına veya tuplea her satır eşleyerek yapılabilir:

val df = rdd.map({ 
    case Row(val1: String, ..., valN: Long) => (val1, ..., valN) 
}).toDF("col1_name", ..., "colN_name") 

veya

case class MyClass(val1: String, ..., valN: Long = 0L) 
val df = rdd.map({ 
    case Row(val1: String, ..., valN: Long) => MyClass(val1, ..., valN) 
}).toDF("col1_name", ..., "colN_name") 

Bu yaklaşımın ana dezavantajı (Bence) Sonuç olarak ortaya çıkan DataFrame şemasını, harita işlevinde, sütun sütununda açıkça ayarlamanız gerekir. Şemaları önceden bilmiyorsanız, bu programlı bir şekilde yapılabilir, ancak işler biraz dağınık olabilir.


2) kullanabilirsiniz createDataFrame(rowRDD: RDD[Row], schema: StructType), SQLContext nesne mevcuttur: Yani, alternatif olarak başka bir seçenek yoktur.Örnek: Herhangi bir şema sütununu açıkça ayarlamanıza gerek olmadığını unutmayın. StructType sınıfındaki eski DF'nin şemasını yeniden kullanıyoruz ve kolayca genişletilebiliyoruz. Ancak, bu yaklaşım bazen mümkün değildir ve bazı durumlarda ilkinden daha az verimli olabilir.

Umarım, öncekinden daha nettir. Şerefe.

+0

Bunu çözdüm, aşağıdakileri kullanarak Veri şemasına eşleştirmem gerekiyordu: valf = testRDD.map {case Satır (n1: Int, n2: Int) => Data (n1, n2)} toDF() ' – TheElysian

+0

Güzel, gerçekten bir seçenek. CreateDataFrame ile çözüm daha geneldir, ancak orijinal veri çerçevesinin kaç alanı olduğunu bilmiyorsanız bile dönüşüme izin verir. –

+0

Kullanmayı denedim, ancak createDataFrame yönteminin taşmasıyla ilgili hatalar alıyorum. Yine de teşekkürler. – TheElysian