在Apache Zeppelin中应用udf时找不到类

时间:2016-10-04 16:52:05

标签: scala apache-spark apache-zeppelin

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

......还有一个巨大的堆栈跟踪。 我猜有一些关于匿名功能的东西但是什么呢?

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,即没有中间名。