2016-08-24 14 views
1

2つのフラグが '1'に設定されたデータフレーム内のすべての行を取得しようとしています。他の等しくない、次のスキーマ(3列)で '1'PySparkの比較演算子(等しくない/!=)

から

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| 
+---+----+----+ 

IアプリをLY希望のフィルタ、第一のフィルタ(FOO = 1、バー= 1)は動作しますが、他の

foobar_df = df.filter((df.foo==1) & (df.bar==1)) 

利回り(FOO = 1 AND NOTは= 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'と等しい列を取得するにはどうすればよいですか? null値をフィルタリングするに

答えて

4

は、なぜそれが

をフィルタリングされていません。そのため、NULLとの比較では、IS NULLIS NOT NULL以外は未定義です。次のいずれかが必要です。

col("bar").isNull() | (col("bar") != 1) 

または

coalesce(col("bar") != 1, lit(True)) 

または(PySpark >= 2.3):

col("bar").eqNullSafe(1) 

あなたはPySparkでヌル安全な比較をしたい場合。

'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| 
## +---+---+----+