Scala中如何判断DataFrame列是否包含列表中的元素?
解决Spark DataFrame判断列是否包含列表中任意元素的问题
嗨,作为Scala+Spark新手,你遇到的问题其实很常见——你用错了方法!isin是用来判断列的值完全等于列表里的某个元素,但你的需求是判断列的内容包含列表里的任意元素,这完全是两个逻辑,而且你原来的代码写法也有问题("description"是字符串,不是Column对象,没法调用isin方法,这就是编译错误的直接原因)。
下面给你两种靠谱的解决方案:
方法一:使用正则表达式(高效推荐)
把你的名称列表拼成一个正则表达式的"或"模式(比如jack|daniel),然后用rlike方法匹配description列。这种方法在列表较大时性能更好,因为只需要做一次正则匹配。
import org.apache.spark.sql.functions.col import java.util.regex.Pattern // 你的名称列表 val listOfLines = Array("jack", "daniel") // 给每个名称加上正则转义(避免名称里有正则特殊字符比如.、*等导致匹配出错) val escapedNames = listOfLines.map(Pattern.quote) // 拼成正则模式:jack|daniel val regexPattern = escapedNames.mkString("|") // 过滤出description包含任意名称的行 val resultDf = df_cleansing.filter(col("description").rlike(regexPattern))
运行后,你的结果会是:
no. |description 12342|my name is jack 2345 |daniel is my neighbour
方法二:使用contains+exists(直观易懂)
如果你的名称列表比较小,也可以用exists遍历列表,对每个名称判断description是否包含它,最后用逻辑或组合这些条件。这种写法更直观,适合新手理解:
import org.apache.spark.sql.functions.col val listOfLines = Array("jack", "daniel") // 构建过滤条件:description包含jack 或者 description包含daniel val filterCondition = listOfLines.exists(name => col("description").contains(name)) val resultDf = df_cleansing.filter(filterCondition)
这个方法的效果和上面一样,但当列表元素很多时,生成的SQL条件会很长,性能不如正则方法。
再说说你原来的代码问题
你写的df_cleansing.filter("description".isin(listOfLines:_*))有两个问题:
"description"是字符串,不是Spark的Column对象,不能调用isin方法——正确获取Column的方式是col("description")或者$"description"。- 即使写法改成
col("description").isin(listOfLines:_*),逻辑也不对,因为它会判断description的值完全等于jack或daniel,但你的description是长句子,所以会过滤不到任何数据。
内容的提问来源于stack exchange,提问作者nitesh jha
相关产品推荐
相关产品推荐

