2016-12-23 94 views
1

我試圖整數包裹陣列在兩個不同的列比較和得到的評分作爲字符串:火花序列[INT]與[字符串]序列輸出中比較

import org.apache.spark.sql.Row 
import org.apache.spark.sql.functions._ 
import scala.collection.mutable.WrappedArray 

數據幀數據具有列A和B由包裹陣列我想比較:

val data = Seq(
    (Seq(1,2,3),Seq(4,5,6),Seq(7,8,9)), 
    (Seq(1,1,3),Seq(6,5,7),Seq(11,9,8)) 
    ).toDF("A","B","C") 

這裏是它的樣子:

data: org.apache.spark.sql.DataFrame = [A: array<int>, B: array<int> ... 1 more field] 
+---------+---------+----------+ 
|  A|  B|   C| 
+---------+---------+----------+ 
|[1, 2, 3]|[4, 5, 6]| [7, 8, 9]| 
|[1, 1, 3]|[6, 5, 7]|[11, 9, 8]| 
+---------+---------+----------+ 

然後這裏是用戶定義函數,我想比較列A和B每行中的配對數組中的每個元素,並給予評級簡單的邏輯。例如,如果A(1)> B(1),那麼D(1)是「頂部」。因此,作爲第一行與列d,我希望能有[「頂」,「頂」,「頂」]

def myToChar(num1: Seq[Int], num2: Seq[Int]): Seq[String] = { 
     val twozipped = num1.zip(num2) 
     for ((x,y) <- num1.zip(num2)) { 
      if (x > y) "Top" 
      if (x < y) "Well" 
      if (x == y) "Good" 
    }} 


val udfToChar = udf(myToChar(_: Seq[Int], _: Seq[Int])) 

val ouput = data.withColumn("D",udfToChar($"A",$"B")) 

不過,我一直得到了<console>:45: error: type mismatch;錯誤信息。不知道我的udf()類型定義是否是錯誤的,並且非常感謝任何指導來糾正我的錯誤。

回答

1

你​​定義聲明爲返回一個Seq[String] - 但其實施不 - 它返回Unit,因爲for表達式(沒有yield條款)具有Unit類型。

您可以通過固定功能的實現解決這個問題:

  • 更換formap操作
  • else將最後if,否則映射函數也返回Unit的輸入,如果條件不符合(與模式匹配不同,編譯器不能斷定你的條件是詳盡的 - 它必須假設它們也沒有一個可能)。

所以 - 正確的實現將是:

def myToChar(num1: Seq[Int], num2: Seq[Int]): Seq[String] = { 
    num1.zip(num2).map { case (x, y) => 
    if (x > y) "Top" 
    if (x < y) "Well" 
    else "Good" 
    } 
} 

或可選擇地使用模式與警衛匹配:

def myToChar(num1: Seq[Int], num2: Seq[Int]): Seq[String] = { 
    num1.zip(num2).map { 
    case (x, y) if x > y => "Top" 
    case (x, y) if x < y => "Well" 
    case _ => "Good" 
    } 
} 
+0

確實感謝您的回答。我可以向你學習'num1.zip(num2).foreach()'與'num1.zip(num2).map()'之間的區別嗎?我愚蠢的想法是'foreach()'將循環遍歷每個元素... –

+0

'map'需要一個函數將每個元素轉換爲一個新元素(可能是一個不同類型),因此會返回一個新的序列和轉換後的元素; 'foreach'期望在每個元素上運行_operates_並且不返回值(在技術上,返回'Unit'),因此'foreach'表達式本身不會返回值(再次 - 'Unit')。因此,當您希望導致某些「副作用」(例如,寫入日誌,保留到磁盤,通過網絡發送等)時,'foreach'非常有用,而'map'在您想要返回值時非常有用。 –