我有一个数据帧,它有一个需要与交叉连接匹配的列表数据类型字段,条件是如果列表中的任何元素存在于另一个列表中,那么这两个记录应该被视为匹配
实施例
import org.apache.spark.sql.functions.udf
val df = sc.parallelize(Seq(("one", List(1,34,3)), ("one", List(1,2,3)), ("two", List(1))))
.toDF("word", "count")
val lsEqual = (xs : (List[Int],List[Int])) => xs._1.find(xs._2.contains(_)).nonEmpty
val equalList = udf(lsEqual)
但是这给了我以下错误
val out = df.joinWith(df,equalList(df("count"),df("count")),"cross")
java.lang.ClassCastException: $anonfun$1 cannot be cast to scala.Function2
at org.apache.spark.sql.catalyst.expressions.ScalaUDF.<init>(ScalaUDF.scala:97)
at org.apache.spark.sql.expressions.UserDefinedFunction.apply(UserDefinedFunction.scala:56)
... 50 elided
还有其他方法可以创建自定义谓词吗?
答案 0 :(得分:0)
您的lsEqual
函数定义似乎有误。 Spark Dataframes 中的List
,Seq
,Array
被视为WrappedArray
。你传递了两个columns
到lsEqual
函数,它应该是两个变量。
正确的方法应该是
val lsEqual = (xs1 : scala.collection.mutable.WrappedArray[Int], xs2 : scala.collection.mutable.WrappedArray[Int]) => xs1.find(xs2.contains(_)).nonEmpty
绝对应该删除你所面临的错误