กรองคอลัมน์ดาต้าเฟรมของ Pyspark ด้วยค่าไม่มี


105

ฉันกำลังพยายามกรองดาต้าเฟรม PySpark ที่มีNoneค่าเป็นแถว:

df.select('dt_mvmt').distinct().collect()

[Row(dt_mvmt=u'2016-03-27'),
 Row(dt_mvmt=u'2016-03-28'),
 Row(dt_mvmt=u'2016-03-29'),
 Row(dt_mvmt=None),
 Row(dt_mvmt=u'2016-03-30'),
 Row(dt_mvmt=u'2016-03-31')]

และฉันสามารถกรองได้อย่างถูกต้องด้วยค่าสตริง:

df[df.dt_mvmt == '2016-03-31']
# some results here

แต่สิ่งนี้ล้มเหลว:

df[df.dt_mvmt == None].count()
0
df[df.dt_mvmt != None].count()
0

แต่มีค่าแน่นอนในแต่ละประเภท เกิดอะไรขึ้น?


คุณต้องการกรองแถวด้วยค่า null ไม่ใช่คอลัมน์ที่ไม่มีค่า ชื่อเรื่องอาจทำให้เข้าใจผิด
Atorpat

โดยสรุปการเปรียบเทียบที่เกี่ยวข้องกับ null (หรือไม่มีในกรณีนี้) จะคืนค่าเท็จเสมอ โดยเฉพาะอย่างยิ่งการเปรียบเทียบ (null == null) ส่งกลับเท็จ นอกจากนี้การเปรียบเทียบ (None == None) จะคืนค่าเท็จ
Richard Gomes

คำตอบ:


217

คุณสามารถใช้Column.isNull/ Column.isNotNull:

df.where(col("dt_mvmt").isNull())

df.where(col("dt_mvmt").isNotNull())

หากคุณต้องการเพียงแค่ปล่อยNULLค่าที่คุณสามารถใช้na.dropกับsubsetอาร์กิวเมนต์:

df.na.drop(subset=["dt_mvmt"])

การเปรียบเทียบตามความเท่าเทียมกันNULLจะไม่ทำงานเนื่องจากใน SQL NULLไม่ได้กำหนดไว้ดังนั้นความพยายามใด ๆ ที่จะเปรียบเทียบกับค่าอื่นจะส่งกลับNULL:

sqlContext.sql("SELECT NULL = NULL").show()
## +-------------+
## |(NULL = NULL)|
## +-------------+
## |         null|
## +-------------+


sqlContext.sql("SELECT NULL != NULL").show()
## +-------------------+
## |(NOT (NULL = NULL))|
## +-------------------+
## |               null|
## +-------------------+

วิธีเดียวที่ถูกต้องในการเปรียบเทียบค่าNULLคือIS/ IS NOTซึ่งเทียบเท่ากับการเรียกisNull/ isNotNullmethod


2
ยอดเยี่ยมขอบคุณ ฉันคิดว่าตัวกรองเหล่านี้บนดาต้าเฟรมของ PySpark น่าจะเป็น "ไพโธนิก" มากกว่า แต่อนิจจาพวกเขาไม่ใช่ ฉันกำลังคิดที่จะถามผู้พัฒนาเกี่ยวกับเรื่องนี้
Ivan

1
จริงๆแล้วมันค่อนข้าง Pythonic คุณไม่ควรตรวจสอบ__eq__กับไม่มี;) และisจะไม่ทำงานเพราะมันไม่ทำงานในลักษณะเดียวกัน
zero323

2
น่าแปลกที่ใช้ได้กับคอลัมน์สตริงเท่านั้น ... ดูเหมือนว่าจะdf.filter("dt_mvmt is not NULL")จัดการทั้งสองอย่าง
David Arenburg


15

เพื่อให้ได้รายการที่มีค่าในdt_mvmtคอลัมน์ไม่เป็นโมฆะเรามี

df.filter("dt_mvmt is not NULL")

และสำหรับรายการที่เป็นโมฆะเรามี

df.filter("dt_mvmt is NULL")

2

หากคุณต้องการใช้ไวยากรณ์ของ Pandas สิ่งนี้ใช้ได้กับฉัน

df = df[df.dt_mvmt.isNotNull()]

2

มีหลายวิธีที่คุณสามารถลบ / กรองค่า null จากคอลัมน์ใน DataFrame

มาสร้าง DataFrame ง่ายๆด้วยโค้ดด้านล่าง:

date = ['2016-03-27','2016-03-28','2016-03-29', None, '2016-03-30','2016-03-31']
df = spark.createDataFrame(date, StringType())

ตอนนี้คุณสามารถลองวิธีใดวิธีหนึ่งด้านล่างเพื่อกรองค่าว่างออก

# Approach - 1
df.filter("value is not null").show()

# Approach - 2
df.filter(col("value").isNotNull()).show()

# Approach - 3
df.filter(df["value"].isNotNull()).show()

# Approach - 4
df.filter(df.value.isNotNull()).show()

# Approach - 5
df.na.drop(subset=["value"]).show()

# Approach - 6
df.dropna(subset=["value"]).show()

# Note: You can also use where function instead of a filter.

คุณยังสามารถตรวจสอบส่วน "การทำงานกับค่า NULL" ในบล็อกของฉันสำหรับข้อมูลเพิ่มเติม

ฉันหวังว่ามันจะช่วยได้


1

ถ้าคอลัมน์ = ไม่มี

COLUMN_OLD_VALUE
----------------
None
1
None
100
20
------------------

ใช้สร้างสิ่งล่อใจบน data frame:

sqlContext.sql("select * from tempTable where column_old_value='None' ").show()

ดังนั้นใช้: column_old_value='None'


0

PySpark มีตัวเลือกการกรองต่างๆตามเงื่อนไขทางคณิตศาสตร์ตรรกะและอื่น ๆ การมีอยู่ของค่า NULL สามารถขัดขวางกระบวนการต่อไป การลบออกหรือคาดเดาทางสถิติอาจเป็นทางเลือก

สามารถพิจารณาชุดรหัสด้านล่าง:

# Dataset is df
# Column name is dt_mvmt
# Before filtering make sure you have the right count of the dataset
df.count() # Some number

# Filter here
df = df.filter(df.dt_mvmt.isNotNull())

# Check the count to ensure there are NULL values present (This is important when dealing with large dataset)
df.count() # Count should be reduced if NULL values are present


0

หากคุณต้องการกรองระเบียนที่ไม่มีค่าในคอลัมน์ให้ดูตัวอย่างด้านล่าง:

df=spark.createDataFrame([[123,"abc"],[234,"fre"],[345,None]],["a","b"])

ตอนนี้กรองบันทึกค่าว่าง:

df=df.filter(df.b.isNotNull())

df.show()

หากคุณต้องการลบบันทึกเหล่านั้นออกจาก DF ให้ดูด้านล่าง:

df1=df.na.drop(subset=['b'])

df1.show()

0

ไม่มี / Null เป็นประเภทข้อมูลของคลาส NoneType ใน pyspark / python ดังนั้นด้านล่างนี้จะไม่ทำงานเนื่องจากคุณพยายามเปรียบเทียบวัตถุ NoneType กับวัตถุสตริง

การกรองผิดวิธี

df [df.dt_mvmt == ไม่มี] .count () 0 df [df.dt_mvmt! = ไม่มี] .count () 0

แก้ไข

df = df.where (col ("dt_mvmt") isNotNull ()) ส่งคืนระเบียนทั้งหมดที่มี dt_mvmt เป็น None / Null

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.