在火花中过滤数据框使用“in a set”子句

Posted

技术标签:

【中文标题】在火花中过滤数据框使用“in a set”子句【英文标题】:filtering a dataframe in spark use "in a set" clause 【发布时间】:2017-02-10 02:03:50 【问题描述】:

我正在使用pyspark。我有一个火花数据框my_sdf,其col1 是整数,我预定义了一个整数列表

S1 = [1,2,3,4]

然后我想返回我的my_sdf 中的行,其中col1 在集合S1 中。所以我做了以下事情:

Test1 = my_sdf.filter(my_sdf.col1 in S1).cache()
# or Test1 = my_sdf.filter(my_sdf.col1 not in S1).cache()
Test1.count()

但它会返回

ValueError:无法将列转换为布尔值:请使用 '&' 表示 'and'、'|' for 'or', '~' for 'not' 在构建 DataFrame 布尔表达式时。

我不知道如何解决这个问题。最后,我想将S1 = [] 作为一个空列表作为我迭代的起点,在循环期间,我将更新S1。同样,not in S1 也不起作用。我试着写了

Test1 = my_sdf.filter((my_sdf.col1 <10) & (my_sdf.col1>2)).cache()

可以,但是如果我使用过滤条件in S1,那就不行了。

另一个问题是:cache() 这个东西在做什么?如果我不放那会有什么不同吗?我被告知 spark 是lazy 用于评估代码,所以在我调用Test.count() 之前,它实际上并没有执行之前的过滤命令。但我不确定这个cache() 的工作原理有多准确。

【问题讨论】:

【参考方案1】:

你可以使用isin

对于您的问题,您可以尝试以下方法:

from pyspark.sql.functions import col

Test1 = my_sdf.where(col("col1").isin(S1))

根据我的理解,缓存用于保存数据帧的当前值。这很有帮助,因为如果您想再次使用该数据帧,spark 将从缓存中获取值,而不是从头开始再次计算。所以,如果你的代码只做Test1.count,那么缓存与否并不重要。 CMIIW

【讨论】:

谢谢!我也玩过,我找到not in,我们可以使用`my_sdf.where((col("col1").isin(S1)) & (~col("col1").isin(S2))) ` 我的另一个问题是:如果S1 不是python 列表,而是一个pyspark 数据框,其中有一列看起来像[Row(S=9527), Row(S=36)],那么我测试了这个isin 函数不起作用.你有什么想法让它继续工作吗?

以上是关于在火花中过滤数据框使用“in a set”子句的主要内容,如果未能解决你的问题,请参考以下文章

在火花数据框中聚合期间过滤数组值

根据火花数据框scala中的列值过滤行

根据上个月和年份过滤火花数据框

根据日期范围过滤火花数据框[重复]

来自数据框的火花过滤器列以及来自集合的单词

如何通过文本框过滤数据表视图中的子表单? #likeoperator #where 子句