我有DataFrame
我想动态创建多个UDF以确定某些行是否匹配。我现在只是测试一个例子。我的测试代码如下所示。
//create the dataframe
import spark.implicits._
val df = Seq(("t","t"), ("t", "f"), ("f", "t"), ("f", "f")).toDF("n1", "n2")
//create the scala function
def filter(v1: Seq[Any], v2: Seq[String]): Int = {
for (i <- 0 until v1.length) {
if (!v1(i).equals(v2(i))) {
return 0
}
}
return 1
}
//create the udf
import org.apache.spark.sql.functions.udf
val fudf = udf(filter(_: Seq[Any], _: Seq[String]))
//apply the UDF
df.withColumn("filter1", fudf(Seq($"n1"), Seq("t"))).show()
但是,当我运行最后一行时,我收到以下错误。
:30: error: not found: value df df.withColumn("filter1", fudf($"n1", Seq("t"))).show() ^ :30: error: type mismatch; found : Seq[String] required: org.apache.spark.sql.Column df.withColumn("filter1", fudf($"n1", Seq("t"))).show() ^
关于我做错的任何想法?注意,我使用的是Scala v2.11.x和Spark 2.0.x.
另一方面,如果我们可以解决这个问题,那就是动态&#34; UDF问题/关注,我的用例是将它们添加到数据帧中。有了一些测试代码如下,它需要永远(它甚至没有完成,我不得不ctrl-c爆发)。我猜测在for循环中做一堆.withColumn
在Spark中是个坏主意。如果是这样,请告诉我,我会完全放弃这种方法。
import spark.implicits._
val df = Seq(("t","t"), ("t", "f"), ("f", "t"), ("f", "f")).toDF("n1", "n2")
import org.apache.spark.sql.functions.udf
val fudf = udf( (x: String) => if (x.equals("t")) 1 else 0)
var df2 = df
for (i <- 0 until 10000) {
df2 = df2.withColumn("filter"+i, fudf($"n1"))
}
答案 0 :(得分:1)
在lit()
df.withColumn("filter1", fudf($"n1", Seq(lit("t")))).show()
尝试在sqlContext
上注册UDF。