我对scala和spark非常陌生,我一直在试图为这个问题找到一整天的解决方案 - 它在做我的头。我尝试了以下代码的20种不同变体,并在尝试对列进行计算时不断得到type mismatch
错误。Spark(scala)dataframes - 检查列中的字符串是否包含集合中的任何项目
我有一个火花数据框,我想检查一个特定列中的每个字符串是否包含来自预定义的List
(或Set
)字的任何数量的字。
这里是复制一些示例数据:
// sample data frame
val df = Seq(
(1, "foo"),
(2, "barrio"),
(3, "gitten"),
(4, "baa")).toDF("id", "words")
// dictionary Set of words to check
val dict = Set("foo","bar","baaad")
现在,我想创建一个比较结果的第三列,看看内他们在$"words"
列中的字符串包含任何的dict
单词组词。所以结果应该是:
+---+-----------+-------------+
| id| words| word_check|
+---+-----------+-------------+
| 1| foo| true|
| 2| bario| true|
| 3| gitten| false|
| 4| baa| false|
+---+-----------+-------------+
首先,我想看看我是否能本身做没有使用UDF的,因为字典设置实际上是一个大字典> 40K字,按照我的理解这个会比UDF更高效:
df.withColumn("word_check", dict.exists(d => $"words".contains(d)))
,但我得到的错误:
type mismatch;
found : org.apache.spark.sql.Column
required: Boolean
我也试图创建一个UDF做到这一点(同时使用mutable.Set
和mutable.WrappedArray
来形容设置 - 不知道这是正确的,但既没有工作):
val checker: ((String, scala.collection.mutable.Set[String]) => Boolean) = (col: String, array: scala.collection.mutable.Set[String]) => array.exists(d => col.contains(d))
val udf1 = udf(checker)
df.withColumn("word_check", udf1($"words", dict)).show()
却得到另一种类型不匹配:
found : scala.collection.immutable.Set[String]
required: org.apache.spark.sql.Column
如果设置为一个固定的号码,我应该能够使用Lit(Int)
的表达式?但我不明白在一列上执行更复杂的功能,通过在scala中混合不同的数据类型。
任何帮助非常感谢,特别是如果它可以有效地完成(这是一个大于5米行df)。
This Works,thank you。但就效率而言,使用40K字典列表可能会非常昂贵。 – renegademonkey