如何创建 UDF 以在数组列中查找索引
How to create a UDF to find index in an array column
我有一个 table 如下:
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, ]|
+---+---------------+
"Dates" 列包含一个字符串数组。如果数组包含目标字符串,我想创建一个可以 return 索引的 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: (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)
将"Array[String]"改成了"Seq[String]",现在可以用了~
您好,Nader Hadji Ghanbari,感谢您的建议~
在 Spark 中,Array 表示为 WrappedArray,类似于带有 Wrapper 的数组。要开始工作,您可以将签名更改为 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)
希望对您有所帮助!
我有一个 table 如下:
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, ]|
+---+---------------+
"Dates" 列包含一个字符串数组。如果数组包含目标字符串,我想创建一个可以 return 索引的 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: (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)
将"Array[String]"改成了"Seq[String]",现在可以用了~ 您好,Nader Hadji Ghanbari,感谢您的建议~
在 Spark 中,Array 表示为 WrappedArray,类似于带有 Wrapper 的数组。要开始工作,您可以将签名更改为 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)
希望对您有所帮助!