2つのフラグが「1」に設定されているデータフレーム内のすべての行を取得しようとしています。その後、2つのうち1つのみが「1」に設定され、その他のNOT EQUALから「1」
次のスキーマ(3列)を使用すると、
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」に等しい列を取得するにはどうすればよいですか?
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
なぜフィルタリングされないのですか
それはSQLであり、NULL
は欠損値を示すためです。そのため、NULL
との比較は、IS NULL
およびIS NOT NULL
は未定義です。次のいずれかが必要です。
col("bar").isNull() | (col("bar") != 1)
または
coalesce(col("bar") != 1, lit(True))
または( PySpark> = 2. ):
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|
## +---+---+----+