筛选具有无值的 Pypark 数据框列

我试图过滤一个 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

但是每个类别都有明确的价值观,这是怎么回事?

444455 次浏览

你可使用 Column.isNull/Column.isNotNull:

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


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

如果只想删除 NULL值,可以使用带 subset参数的 na.drop:

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比较值的唯一有效方法是与 isNull/isNotNull方法调用等效的 IS/IS NOT

尽量使用 是 NotNull函数。

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

为了获得 dt_mvmt列中值不为 null 的条目,我们有

df.filter("dt_mvmt is not NULL")

对于空的条目,我们有

df.filter("dt_mvmt is 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

如果要筛选出列中包含“无值”的记录,请参见下面的示例:

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()

如列 = 无

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

在数据帧上创建一个诱饵:

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

所以使用: column_old_value='None'

如果你想保持熊猫综合体,这对我很有效。

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

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

希望能有所帮助。

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为 Nothing/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()

两者都将返回相同的结果