在&子句中带有布尔值和字符串的Pyspark数据框过滤条件

时间:2019-07-22 19:54:57

标签: apache-spark pyspark

我有一个非常基本的Dataframe过滤条件,我需要放置2个过滤条件。这是我的数据框-

sqlContext.createDataFrame([('1000000','ABCD','20190516'),('1000000','ABCD','20190516'),('1000000','ABCD','20120516'),('5000000','WXYZ','20110516'),('2000000','PQRS','20140516'),('3000000','PQRS','20160516'),('3000000','PQRS','20150516')],['hashVal','prodCode','date'])
>>> df.show()
+-------+--------+--------+
|hashVal|prodCode|    date|
+-------+--------+--------+
|1000000|    ABCD|20190516|
|1000000|    ABCD|20190516|
|1000000|    ABCD|20120516|
|5000000|    WXYZ|20110516|
|2000000|    PQRS|20140516|
|3000000|    PQRS|20160516|
|3000000|    PQRS|20150516|
+-------+--------+--------+

要求是-

  1. 如果prodCode位于(“ ABCD”,“ WXYZ”)中,则我需要此Dataframe中所有不同的记录
  2. 如果prodCode不在这两个值中的任何一个(“ ABCD”,“ WXYZ”)中,那么我只需要> 2014201416的不同记录即可。

所以想要的是-

+-------+--------+--------+
|hashVal|prodCode|    date|
+-------+--------+--------+
|1000000|    ABCD|20120516|
|5000000|    WXYZ|20110516|
|1000000|    ABCD|20190516|
|3000000|    PQRS|20160516|
|3000000|    PQRS|20150516|
+-------+--------+--------+

如果我尝试使用以下代码-

df.where(( col("prodCode").isin (["ABCD","WXYZ"])) | (  ~( col("prodCode").isin(["ABCD","WXYZ"])) & col("date")>"20140516"  ) ).distinct()

这给了我错误-

  

u“由于数据类型不匹配而无法解析'(NOT prodCode IN(ABCD,WXYZ)&& date)':'(NOT prodCode IN(ABCD,WXYZ)&& date)'中的类型不同(布尔值和字符串)。 ;“

如果我只打破两个条件,我确实得到了正确的解决方案,但是使用这种解决方案,我必须执行我希望避免的联合。

dfA = df.where( ( col("prodCode").isin (["ABCD","WXYZ"])) ).distinct()
dfB = df.where(~( col("prodCode").isin (["ABCD","WXYZ"])) ).where(col("date")>"20140516").distinct()
dfF = dfA.unionAll(dfB)

我如何使其工作而不必将我的数据框分为2种不同的条件,然后再次合并?

1 个答案:

答案 0 :(得分:1)

您在条件周围缺少括号。如果存在多个条件,则应在每个条件中加上括号。另外,这里的条件之一在其中包括AND。确保各个条件也用括号分隔,以获得所需的结果。与A OR B AND C相比,A OR (B AND C)给出了不同的结果。

话虽如此,您的情况应该是

df.where((col("prodCode").isin (["ABCD","WXYZ"])) | ((~(col("prodCode").isin(["ABCD","WXYZ"]))) & (col("date")>"20140516"))).distinct()