2017-06-10 57 views
1

這裏很新。我試圖將數據幀(2列a和b)轉換爲case類,在列A上使用函數mathAdd,並將列放在新列C.我知道函數.withColumn,但我真的不知道如何把這些放在一起。以下是我對評論的嘗試。任何人都可以請幫忙?非常感謝。 *編輯:我想要使用case類的原因之一是因爲我想保存這些函數以供重用。如何在Scala case類中應用函數來轉換數據框

dfTest.createOrReplaceTempView("testTable") 

    case class testclass (a:Int,b:String){ 
    var result = 0  
    def mathAdd ={ 
     if (b=="apple"){ 
      result=a+1 
     } else{ 
      result=a+2 
    // but how to put 'var result' into a column? 
    } 
    } 
} 

var toTestClass = sqlContext.table("testTable").as[testclass] 
toTestClass.mathAdd() 
//After this how can I convert this testclass back to dataframe? 
+0

如果您必須將數據集轉換回數據幀,爲什麼如此複雜,當您已經有一個datafram e,您可以輕鬆實現數據框所需的內容嗎? –

+0

因爲在現實生活中,功能會更復雜,對於數據幀API可能太複雜了。 – user4046073

+0

不,我猜不。請參閱下面的答案,如果您仍然認爲它很複雜,那麼我們將研究您認爲會很複雜的案例分類方法。 –

回答

1

你可以調用您的實例方法map

case class testclass(a: Int, b: String) { 
    var result = 0 

    def mathAdd: Int = { 
     if (b == "apple") { 
     result = a + 1 
     } else { 
     result = a + 2 
     } 
     return result 
    } 
    } 

val tansformed = sqlContext.table("testTable").as[testclass].map(tc => tc.mathAdd) 

這將讓你一個Dataset[Int]

但我寧願定義mathAdd作爲一個單獨的方法,通常情況下,類不認爲含有邏輯:

case class testclass(a: Int, b: String) 

def mathAdd(tc: testclass): Int = { 
    if (tc.b == "apple") { 
    tc.a + 1 
    } else { 
    tc.a + 2 
    } 
} 

val tansformed = sqlContext.table("testTable").as[testclass].map(tc => mathAdd(tc)) 
+0

第二種方法出錯說'重新分配到val',我猜你不能更改列的值? – user4046073

+0

謝謝。第一個雖然工作。 – user4046073

+1

@ user4046073它適用於我(請參閱http://83.169.17.150:9001/notebooks/Test.snb) –

1

你可以實現你打算做case class簡單when功能和withColumn API

import org.apache.spark.sql.functions._  
df.withColumn("newCol", when(col("b") === "apple", col("a")+1) otherwise(col("a")+2)) 

所以我猜你不需要case class什麼。

+1

顯然這個邏輯比問題中的例子複雜得多,我也建議把這個邏輯打包成一個普通的scala函數,而不是使用spark函數 –

相關問題