ChatGPT解决这个技术问题 Extra ChatGPT

使用 None 值过滤 Pyspark 数据框列

我正在尝试过滤具有 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

但是每个类别肯定都有价值。这是怎么回事?

您实际上想要过滤具有空值的行,而不是具有无值的列。标题可能具有误导性。
简而言之,涉及 null(或 None,在这种情况下)的比较总是返回 false。特别是,比较 (null == null) 返回 false。此外,比较 (None == None) 返回 false。

z
zero323

您可以使用 Column.isNull / Column.isNotNull

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

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

如果您想简单地删除 NULL 值,您可以将 na.dropsubset 参数一起使用:

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 方法调用。


太好了,谢谢。我认为 PySpark 数据帧上的这些过滤器会更“pythonic”,但唉,事实并非如此。我正在考虑向开发人员询问这个问题。
实际上它非常Pythonic。您永远不应该检查 __eq__ 和 None ;) 并且 is 不起作用,因为它的行为方式不同。
奇怪的是,这仅适用于字符串列......似乎 df.filter("dt_mvmt is not NULL") 处理两者。
A
Anthony

尝试只使用 isNotNull 功能。

df.filter(df.dt_mvmt.isNotNull()).count()

t
timctran

要获取 dt_mvmt 列中的值不为空的条目,我们有

df.filter("dt_mvmt is not NULL")

对于为空的条目,我们有

df.filter("dt_mvmt is NULL")

N
Neeraj Bhadani

有多种方法可以从 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 值”部分了解更多信息。

我希望它有所帮助。


P
Purushothaman Srikanth

isNull()/isNotNull() 将返回具有 dt_mvmt 为 Null 或 !Null 的相应行。

method_1 = df.filter(df['dt_mvmt'].isNotNull()).count()
method_2 = df.filter(df.dt_mvmt.isNotNull()).count()

两者都将返回相同的结果


S
Suraj Rao

如果列 = 无

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

使用在数据框上创建一个临时表:

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

所以使用:column_old_value='None'


P
Paul Roub

如果您想保留 Pandas 语法,这对我有用。

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

P
Purushothaman Srikanth

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 的所有记录


S
Swaminathan Meenakshisundaram

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

A
AS Mackay

如果要过滤掉列中具有 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()