2017-06-20 50 views
1

我有一個表如下:如何創建一個UDF找到索引數組列

val question = sqlContext.createDataFrame(Seq((1, Seq("d11","d12","d13")), (2, Seq("d21", "d22", "")))).toDF("Id", "Dates") 
+---+---------------+ 
| Id|   Dates| 
+---+---------------+ 
| 1|[d11, d12, d13]| 
| 2| [d21, d22, ]| 
+---+---------------+ 

的「日期」欄包含字符串數組。我想創建一個udf,如果數組包含目標字符串,可以返回索引。 我試着寫一個像這樣的UDF:

def indexOf(s: String) = udf((n: Array[String]) => if (n.contains(s)) 
n.indexOf(s) else -1) 

question.withColumn("index", indexOf("d11")(question("Dates"))).show() 

但是,我得到了一個錯誤信息是這樣的:

org.apache.spark.SparkException: Failed to execute user defined function($anonfun$indexOf$1: (array<string>) => int) 

有什麼事去可怕的錯誤嗎?

更新: 我還發現有一個錯誤消息是這樣的:

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

所以我修改我的UDF爲:

def indexOf(s: String) = udf((n: Seq[String]) => if (n.contains(s)) n.indexOf(s) else -1) 

更改了 「數組[字符串]」 到「序列[字符串]「,它現在正在工作〜 嗨,納德哈吉·甘巴里,感謝您的建議〜

回答

1

在Spark中,數組表示爲一個WrappedArray,它類似於帶有包裝的n數組。爲了得到工作,您可以將簽名更改爲Seq,WrappedArray或List。

def indexOf(s: String) = udf((n: Seq[String]) => 
    if (n.contains(s)) n.indexOf(s) else -1) 

或者

def indexOf(s: String) = udf((n: WrappedArray[String]) => 
    if (n.contains(s)) n.indexOf(s) else -1) 

或者

def indexOf(s: String) = udf((n: List[String]) => 
    if (n.contains(s)) n.indexOf(s) else -1) 

希望這有助於!

相關問題