我正在尝试过滤具有 None
作为行值的 PySpark 数据框:
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
但是每个类别肯定都有价值。这是怎么回事?
您可以使用 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
/ isNotNull
方法调用。
要获取 dt_mvmt
列中的值不为空的条目,我们有
df.filter("dt_mvmt is not NULL")
对于为空的条目,我们有
df.filter("dt_mvmt is 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.
您还可以查看我的 blog 上的“使用 NULL 值”部分了解更多信息。
我希望它有所帮助。
isNull()
/isNotNull()
将返回具有 dt_mvmt
为 Null 或 !Null 的相应行。
method_1 = df.filter(df['dt_mvmt'].isNotNull()).count()
method_2 = df.filter(df.dt_mvmt.isNotNull()).count()
两者都将返回相同的结果
如果列 = 无
COLUMN_OLD_VALUE
----------------
None
1
None
100
20
------------------
使用在数据框上创建一个临时表:
sqlContext.sql("select * from tempTable where column_old_value='None' ").show()
所以使用:column_old_value='None'
如果您想保留 Pandas 语法,这对我有用。
df = df[df.dt_mvmt.isNotNull()]
None/Null 是 PySpark/Python 中 NoneType 类的数据类型,因此,当您尝试将 NoneType 对象与字符串对象进行比较时,下面将不起作用
错误的过滤方式
df[df.dt_mvmt == None].count()
0
df[df.dt_mvmt != None].count()
0
正确的
df=df.where(col("dt_mvmt").isNotNull())
返回 dt_mvmt
为 None/Null 的所有记录
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
如果要过滤掉列中具有 None 值的记录,请参见下面的示例:
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()
__eq__
和 None ;) 并且is
不起作用,因为它的行为方式不同。df.filter("dt_mvmt is not NULL")
处理两者。