None(null) 和NaN的区别联系和空值处理

文章详细介绍了Python中的None、在Pandas和PySpark中对应的null,以及浮点数空值NaN的区别。在PySpark中,None转换为null,而NaN用于数值类型的空值。文章讨论了如何使用fillna函数填充缺失值,以及如何通过where或filter方法过滤含空值的行。此外,提到了在PySpark中处理NaN需借助isnan函数。
部署运行你感兴趣的模型镜像

对于python语言中,在pandas 和 pyspark以及普通的python代码中经常遇到空值需要处理的情况,有时见到的是None,有时是null,有时是NaN,本文尝试对这三者进行一个汇总,和对于pyspark中关于空值的处理进行汇总。 

目录

一 、含义区分: 

None 和null 

 NaN

二、缺失值填充-dataframe.fillna函数 和 dataframe.na.fill函数  

三、含有空值的过滤 


一 、含义区分: 

None 和null 

在python代码中并没有直接的的null,但是有和其意义相近的None。对于当None值被写入在python相关的pandas 和pyspark 的dataframe中时,其表示便是null 。 

None表示空值,它是一个特殊 Python 对象, None的类型是NoneTypeNone 是 NoneType 数据类型的唯一值,我们不能再创建其它 NoneType 类型的变量,但是可以将 None 赋值给任何变量。

print(type(None))

# 输出 <class 'NoneType'>

在spark中,定义df时的输入为none,进入df后的表示便是null。 

df = spark.createDataFrame([(None, 2.0),(1.0,3.0)], ("a", "b"))
df.show()

输出: 

+----+---+
|   a|  b|
+----+---+
|null|2.0|
| 1.0|3.0|
+----+---+

另外: 对于所有没有 return 语句的函数定义,Python 都会在末尾加上 return None,使用不带值的 return 语句(也就是只有 return 关键字本身),那么就返回 None。

 NaN

NaN本身是浮点数的空值。 当使用Numpy或者Pandas处理数据的时候,经常会遇到条目中没有数据,然后当我们在去打印的时候就会出现NaN。

import numpy as np 
print(type(np.nan)) 

输出: <class 'float'>

注意: 和任何值做计算的结果都是NaN

如: print(np.nan+20.5 )  ,不会报错,但是结果为nan

在pyspark 的dataframe中也可以用float('nan') 去给相关字段值,此时得到的值并不能被isnull识别,必须要调用 isnan

两者在pyspark中的对比联系案例

# 两种类型的空值,一种是普通的缺失值,另一种是在数值型字段中有时专门指定的'nan’值。普通的缺失值,在建df时可以用None指定。
df = spark.createDataFrame([ (None, 2.0),(1.0, float('nan'))], ("a", "b"))
df.show()
+----+---+
|   a|  b|
+----+---+
|null|2.0|
| 1.0|NaN|
+----+---+

from pyspark.sql.functions import isnull,isnan
print(df.select(isnull('a').alias('r1')).show()) # 对于a列定义时的None已经转换为Null
print(df.select(isnan('a').alias('r1')).show()) # None并不能被isnan识别
print(df.filter(df.b.isNull()|df.a.isNull()).show())# b这列的NaN并不能被isnull识别,nan并不会认为是null,

输出: 

+-----+
|   r1|
+-----+
| true|
|false|
+-----+
+-----+
|   r1|
+-----+
|false|
|false|
+-----+
+----+---+
|   a|  b|
+----+---+
|null|2.0|
+----+---+

二、缺失值填充-dataframe.fillna函数 和 dataframe.na.fill函数  

spark dataframe 的 fillna 函数等同于 .na.fill(),.na.fill 函数底层也是调用 fillna,它的作用是填充列值 null 为指定的值,对于Nan 和None 都可以进行填充。替换的列可以指定,每列的替换规则也可以通过 dict 字典参数设置.

fillna(self, value, subset=None) ,另一个别名函数 na.fill() 函数,该函数是版本 1.3.1 开始新增的。

  • 参数 value 支持 2 大形式:

    第一种形式是接收 intlongfloatstringbool 固定值设置,这种一般和后面的 subset 参数一起使用,将指定的字段统一改为指定值。

    第二种形式是 dict 字典类型,设置具体字段或列的值映射,这种形式会忽略后面的 subset 参数设置,因为后面的字段指定无意义。

  • subset 参数是可选项,指定要填充的字段或列列表,和 value 参数的第一种形式搭配使用。如果不设置,则表示作用于所有字段;如果设置的字段类型与设置值的类型不匹配,该字段值的替换则忽略,即不生效。

df.fillna({'a':20,'b':40}).show() ## 对于Nan 和None 都进行了填充,说明.fillna对于NaN和None(null)都能识别。
结果: 

+----+----+
|   a|   b|
+----+----+
|20.0| 2.0|
| 1.0|40.0|
+----+----+

三、含有空值的过滤 

对于None或者Null ,两种方式,一种使用标准ANSI-SQL SQL表达式来过滤列得到函空值的对应的行 ,另一种使用column自带的.BooleanType列对象

## 方式1  使用标准ANSI-SQL SQL表达式来过滤列
print(df.where('a is null ').show()) 
print(df.filter('a is null').show())

## 方式2 使用type.BooleanType列对象来过滤
print(df.where(df['a'].isNull()).show())
结果都是: 

+----+---+
|   a|  b|
+----+---+
|null|2.0|
+----+---+

注意: 对于缺失值Nan, pyspark的dataframe中并没有 isNaN,

 print(df.where(df['b'].isNaN()).show())## 此处报错
# 对于pyspark的dataframe 里,column有isNull但是没有isNan的判断。isNan 要借助pyspark.functions里的nan

from pyspark.sql.functions import isnull,isnan
df = spark.createDataFrame([ (None, 2.0),(1.0, float('nan'))], ("a", "b"))
print(df[isnan('b').alias('rb')].show()) # isnan可以识别出来。
输出: 

+---+---+
|  a|  b|
+---+---+
|1.0|NaN|
+---+---+

如果觉得本文对你有所帮助,还请帮忙点个赞或者收藏,非常感谢!

参考: 

PySpark SQL:过滤带有None或Null值的列

pyspark系列--datafrane进阶

pyspark系列--datafrane进阶 - 知乎

您可能感兴趣的与本文相关的镜像

Python3.11

Python3.11

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

Python中,NaN(Not a Number)None是两种不同的空值表示,它们在类型、处理方式应用场景等方面存在明显区别: ### 类型 - **None**:是Python内置的常量,属于NoneType类型,没有长度,布尔值为False,即`bool(None) == False` [^3]。 - **NaN**:在pandas中是缺失值的意思,在Python中导入方式为`from numpy import nan`或者`from numpy import NaN`,使用`type()`判断其类型为float [^3]。 ### 数据处理 - **pandas中的自动替换**:在pandas里,如果其他数据都是数值类型,pandas会把None自动替换成NaN,像`s[s.isnull()] = None``s.replace(NaN, None)`操作可能无效,此时需用`where`函数进行替换 [^1]。 - **计算处理**:在Python 3.7中,NaNNone都可以是float类型,都能数值做加法运算。但如果是NaN类型,运算不会报错,例如`np.nan + 1`结果为`nan`;而numpypandas的很多函数能处理NaN,遇到None则会报错 [^2][^3]。 - **判断方法**:判断是否为NaN需要用相应函数,如`np.isnan()` 、`math.isnan()`、`pandas.isna()`、`pandas.isnull()` ;而None可直接通过`is None`判断 [^2][^3]。 ### 数据库导入 None能够直接被导入数据库作为空值处理,包含NaN的数据导入时会报错 [^1]。 ### 分组处理 NoneNaN都不能被pandas的`groupby`函数处理,包含None或者NaN的组都会被忽略 [^1]。 ### 代码示例 ```python import numpy as np import pandas as pd # 类型判断 print(type(None)) # <class 'NoneType'> print(type(np.nan)) # <class 'float'> # 布尔值判断 print(bool(None)) # False # 计算处理 print(np.nan + 1) # nan # 判断方法 print(np.isnan(np.nan)) # True print(None is None) # True ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值