LATER EDIT:似乎问题与Apache Zeppelin解释器有关。我在Spark 1.6.0上使用Apache Zeppelin 0.6.0。在spark-shell(2.0.0)中运行相同的代码时没有问题。
这可能有点过于具体,但也许它可以帮助其他人在UDF中遇到类似的错误。
我想要的是基于该DF中的不同列和Seq字符串在Spark Dataframe中创建列。 因此,创建列“urban”,如果“location”列中的值位于“cities”序列中,则输入1,否则输入0。
尝试用几种不同的方式解决它。我犯了同样的错误。最终版本基于以下帖子: Use of Seq.contains(String) 和 Create new column with udf。这就是我现在所拥有的:
val cities = Seq("london", "paris")
df.filter(lower($"location") isin (cities : _*)).count()
长= 5485947 所以我有这两个地点的记录
import org.apache.spark.sql.functions._
val urbanFlag: (String => Int) = (arg: String) => {if (cities.contains(arg)) 1 else 0}
val urbf = udf(urbanFlag)
df.withColumn("urban", urbf(lower($"location"))).show(100)
当我运行这个时,我得到“由于阶段失败而中止作业”,错误:
抛出java.lang.ClassNotFoundException: $ $$ IWC IWC $$ IWC $$ IWC $$ IWC $$$$ 725d9ae18728ec9520b65ad133e3b55 $$$$$$ IWC $$ IWC $$ IWC $$ IWC $$ IWC $$ IWC $$ IWC $$ anonfun $ 1
......还有一个巨大的堆栈跟踪。 我猜有一些关于匿名功能的东西但是什么呢?
答案 0 :(得分:1)
您的定义UDF的方式可能存在问题吗?这对我有用:
import org.apache.spark.sql.functions._
val data = sqlContext.read.json(sc.parallelize(Seq("{'location' : 'london'}", "{'location': 'tokyo'}")))
val cities = Seq("london", "paris")
val urbf = udf { city: String => if (cities.contains(city)) 1 else 0 }
data.select($"location", urbf($"location")).show
+--------+-------------+
|location|UDF(location)|
+--------+-------------+
| london| 1|
| tokyo| 0|
+--------+-------------+
请注意,我直接定义了UDF,即没有中间名。