我试图获得数据帧中的所有行,其中两个标志设置为'1',随后所有那些只有两个中的一个设置为'1'而另一个NOT EQUAL为'1'
使用以下模式(三列),
df = sqlContext.createDataFrame([('a',1,'null'),('b',1,1),('c',1,'null'),('d','null',1),('e',1,1)], #,('f',1,'NaN'),('g','bla',1)],
schema=('id', 'foo', 'bar')
)
我得到以下数据帧:
+---+----+----+
| id| foo| bar|
+---+----+----+
| a| 1|null|
| b| 1| 1|
| c| 1|null|
| d|null| 1|
| e| 1| 1|
+---+----+----+
当我应用所需的过滤器时,第一个过滤器(foo=1 AND bar=1)有效,但另一个过滤器(foo=1 AND not bar=1)无效
foobar_df = df.filter( (df.foo==1) & (df.bar==1) )
收益率:
+---+---+---+
| id|foo|bar|
+---+---+---+
| b| 1| 1|
| e| 1| 1|
+---+---+---+
这是不正常的过滤器:
foo_df = df.filter( (df.foo==1) & (df.bar!=1) )
foo_df.show()
+---+---+---+
| id|foo|bar|
+---+---+---+
+---+---+---+
为什么不过滤?我怎样才能得到只有foo等于1的列呢?
为什么不过滤
因为它是SQL, NULL
表示缺失值。因此,除IS NULL
和IS NOT NULL
外,任何与NULL
的比较都是不确定的。您需要:
col("bar").isNull() | (col("bar") != 1)
或
coalesce(col("bar") != 1, lit(True))
or (PySpark>= 2.3):
col("bar").eqNullSafe(1)
如果你想在PySpark中null安全比较。
'null'
也不是引入NULL
文字的有效方式。您应该使用None
来指示丢失的对象。
from pyspark.sql.functions import col, coalesce, lit
df = spark.createDataFrame([
('a', 1, 1), ('a',1, None), ('b', 1, 1),
('c' ,1, None), ('d', None, 1),('e', 1, 1)
]).toDF('id', 'foo', 'bar')
df.where((col("foo") == 1) & (col("bar").isNull() | (col("bar") != 1))).show()
## +---+---+----+
## | id|foo| bar|
## +---+---+----+
## | a| 1|null|
## | c| 1|null|
## +---+---+----+
df.where((col("foo") == 1) & coalesce(col("bar") != 1, lit(True))).show()
## +---+---+----+
## | id|foo| bar|
## +---+---+----+
## | a| 1|null|
## | c| 1|null|
## +---+---+----+
要过滤空值,请尝试:
foo_df = df.filter( (df.foo==1) & (df.bar.isNull()) )
https://spark.apache.org/docs/1.6.2/api/python/pyspark.sql.html pyspark.sql.Column.isNull