2017-04-13 79 views
1

我有一個火花數據幀,其中一列由列表的索引組成。我想寫一個udf,它允許我創建一個與索引相關的值的新列。spark數據幀udf映射索引值

E.g.

假設我有以下的數據幀和數組:

val df = spark.createDataFrame(Seq((0, Array(1, 1, 2)), (1, Array(1, 2, 0)))) 
df.show() 
+---+---------+ 
| _1|  _2| 
+---+---------+ 
| 0|[1, 1, 2]| 
| 1|[1, 2, 0]| 
+---+---------+ 
val sArray = Array("a", "b", "c") 

我希望能夠在indicies在_2自己的價值觀在sArray映射導致這種:

+---+---------+---------+ 
| _1|  _2|  _3| 
+---+---------+---------+ 
| 0|[1, 1, 2]|[b, b, c]| 
| 1|[1, 2, 0]|[b, c, a]| 
+---+---------+---------+ 

我有一直試圖做到這一點與udf:

def indexer (values: Array[String]) = 
    udf((indices: Array[Int]) => indices.map(values(_))) 
df.withColumn("_3", indexer(sArray)($"_2")) 

但是,當我這樣做時,出現以下錯誤:

Failed to execute user defined function

... Caused by: java.lang.ClassCastException: scala.collection.mutable.WrappedArray$ofRef cannot be cast to [I

這裏發生了什麼問題?我怎樣才能解決這個問題?

+2

的可能的複製[如何轉換WrappedArray列火花數據幀爲字符串?](http://stackoverflow.com /問題/ 34539068 /如何-DO-I-轉換-A-wrappedarray列式火花非數據幀到字符串) –

回答

5

當在DataFrame中的ArrayType列上操作時,傳遞到UDF的實際類型是mutable.WrappedArray。您看到的失敗是試圖將此WrappedArray轉換爲您的函數期望的Array[Int]的結果。

解決方法是相當簡單 - 定義函數期待一個mutable.WrappedArray[Int]

def indexer (values: Array[String]): UserDefinedFunction = { 
    udf((indices: mutable.WrappedArray[Int]) => indices.map(values(_))) 
}