我有一个如下表:
+---+----+----+
| id|Sell| Buy|
+---+----+----+
| A|null|null|
| B| Y| Y|
| C|null| Y|
| D| Y|null|
| E|null|null|
+---+----+----+
当值等于"0"时,我可以容易地过滤单个或两个列;Y";。例如,当两个列都是";Y":
df.filter((df["Buy"] == "Y") & (df["Sell"] == "Y"))
然而,当单列或两列不相等时,我如何进行筛选;Y";??每个案例的代码是什么?我试过这些代码,它们不返回行:
df.filter((df["Buy"] != "Y") & (df["Sell"] != "Y"))
df.filter(~((df["Buy"] == "Y") | (df["Sell"] == "Y")))
它似乎没有捕获空值
我认为问题是它们是null,null值在某种程度上是特殊的
尝试过滤Buy
不是Y 的值
df.filter((df["Buy"] != "Y") | (df["Buy"].isNull()))
因此,如果你想根据你的尝试过滤买入和卖出不是"Y"的地方,你需要这样做:
df.filter((df["Buy"] != "Y") | (df["Buy"].isNull()) & (df["Sell"] != "Y") | (df["Sell"].isNull()))
快速示例:
输入
+---+----+----+
| id|Sell| Buy|
+---+----+----+
| A|null|null|
| B| Y| Y|
| C| Y|null|
| D| Y|null|
| E|null|null|
+---+----+----+
输出
>>> df.filter((df["Buy"] != "Y") | (df["Buy"].isNull())).show(10)
+---+----+----+
| id|Sell| Buy|
+---+----+----+
| A|null|null|
| C| Y|null|
| D| Y|null|
| E|null|null|
+---+----+----+
>>> df.filter((df["Buy"] != "Y") | (df["Buy"].isNull()) & (df["Sell"] != "Y") | (df["Sell"].isNull())).show(10)
+---+----+----+
| id|Sell| Buy|
+---+----+----+
| A|null|null|
| E|null|null|
+---+----+----+
简单的修复方法是使用空安全运算符
df.filter(~((df["Buy"].eqNullSafe("Y")) | (df["Sell"].eqNullSafe("Y"))))
首先填充空值并进行筛选。
df.na.fill('N')
.filter("Sell != 'Y' or Buy != 'Y'")
.show(10, False)
df.na.fill('N')
.filter("Sell != 'Y' and Buy != 'Y'")
.show(10, False)
+---+----+---+
|id |Sell|Buy|
+---+----+---+
|A |N |N |
|C |N |Y |
|D |Y |N |
|E |N |N |
+---+----+---+
+---+----+---+
|id |Sell|Buy|
+---+----+---+
|A |N |N |
|E |N |N |
+---+----+---+
您总是可以尝试使用spark SQL,方法是创建一个临时视图并在SQL中自然地编写查询。比如为此我们可以写
df.createOrReplaceTempView('filter_value_not_equal_to_Y')
filterNotEqual=spark.sql("Select * from filter_value_not_equal_to_Y where Sell <>'Y' or Buy <>'Y'")
display(filterNotEqual)