缺省值判断 pd.isnull, pd.isna, pd.notna, pd.notnull, np.isnan, math.isnan 区别

文章目录

  • 1、基础知识准备
      • (1) np.nan != np.nan
        • 代码示例
      • (2) nan和None
        • 代码示例
      • (3) pandas 中将nan和None都处理为np.nan
        • 代码示例
      • (4) np.nan is np.nan返回True;np.nan == np.nan返回False.
        • 代码示例
      • (5) Pandas中的Nullable类型的作用?
      • (6) DataFrame、Series中排序时NAN值不参与
        • 代码示例
      • (7) math.nan和np.nan
        • 代码示例
  • 2、pd.isnull == pd.isna
      • (1) 有趣的现象
      • (2) 原因
  • 3、注意pd.DataFrame.isna() 和pd.isna()
      • 1、区别
      • 2、代码示例

1、基础知识准备

(1) np.nan != np.nan

在计算机中本没有绝对绝对相等的数据,所谓的相等只是精度允许的条件下相等!np.nan 原意为 not a number。
概括:

  • 对某个值是否为nan进行判断,只能用np.isnan(i),绝不可用 i == np.nan 来判断,因为nan具有不等于自身的属性,应该使用np.isnan来测试nan值,如np.isnan(np.nan)将产生True;
  • np.nan非空对象,其类型为基本数据类型float

代码示例

c = np.array([ 1.,  2., np.nan,  3.,  4.])
np.isnan(c)
>>> array([False, False,  True, False, False])

np.nan in c  # 不能用这种方式判断 ndarray 中是否存在 np.nan
>>> False

np.nan == np.nan
>>> False

# 因为
np.min(c)
>>> nan
np.sum(c)
>>> nan
# 所以也可以通过下面的方式来判断数组中是否存在np.nan
np.isnan(np.min(c))
>>> True
np.isnan(np.sum(c))
>>> True

(2) nan和None

  • python自带的 None ,为 NoneType 类型, 代表空类型,不能参与运算
  • numpy中的 isnan 对应的是 NaN 值,代表“不是数字”,数值类型为 float ,数组中显示为nan,能参与运算,但结果显示为NaN;

代码示例

np.nan + 3            
>>> nan

a = np.array([1,2,3,np.nan])
np.isnan(a)
>>> array([False, False, False,  True])

a = np.array([1,2,3,None])
np.isnan(a)        # 报类型错误警告 None并不代表NaN值无法处理
>>> TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

a = np.array(['1','2','3',np.nan])
np.isnan(a)        #类型错误警告,字符类型无法运算
>>> TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

np.nan == np.nan
>>> False

np.isnan(np.nan)
>>> True

np.nan is None
>>> False

type(np.nan)
>>> float

(3) pandas 中将nan和None都处理为np.nan

代码示例

df1 = DataFrame(data=np.random.randint(0,20,size=(5,5)),columns=list("abcde"))
df1["b"].iloc[1] = None
df1["c"].iloc[2] = None
df1.loc[2, "d"] = np.nan # 显式地去设置nan不太好
df1
>>> 
    a	b    c	   d	e
0	19	12.0 18.0  14	11
1	11	NaN	 4.0   13	6
2	5	5.0  NaN   NaN	0
3	9	3.0	 8.0   13	13
4	5	2.0	 9.0   8	6

可以看到两者都被处理成NaN值。

(4) np.nan is np.nan返回True;np.nan == np.nan返回False.

代码示例

id(np.nan)
>>> 2345077159808

id(np.nan)
>>> 2345077159808

id(np.nan) == id(np.nan)
>>> True

np.nan is np.nan
>>> True

np.nan == np.nan
>>> False

(5) Pandas中的Nullable类型的作用?

Nullable 类型是pandas的扩展类型,用于表示标量的缺失值且不改变数据类型。
由于 NaN , None 与 NaT 三种缺失值在功能和类型上的混乱与交叉, Nullable 类型它的设计目的在于可以提供一种能够一致使用的缺失标识符,用于处理 NaN , None 与 NaT 三种缺失字符在不同情况下的类型转化,将三种缺失值都替换为统一的 NA 符号,且不改变数据类型。

(6) DataFrame、Series中排序时NAN值不参与

  • Series.sort_values(axis=0, ascending=True, inplace=False, kind=‘quicksort’, na_position=‘last’, ignore_index=False, key=None)
  • DataFrame.sort_values(by, axis=0, ascending=True, inplace=False, kind=‘quicksort’, na_position=‘last’, ignore_index=False, key=None)
  • 排序时,nan值会默认排在最后,也可通过na_position='first’将nan值排在最前面。

代码示例

df = pd.DataFrame({
     'A':[1,5,3,2],'B':[2,np.nan,4,0],'C':[3,5,np.nan,1]})
df
>>> 
    A	B	 C
0	1	2.0	 3.0
1	5	NaN	 5.0
2	3	4.0	 NaN
3	2	0.0	 1.0

df.sort_values(by=['B'])
df
>>> 
    A	B	 C
0	1	2.0	 3.0
1	5	NaN	 5.0
2	3	4.0	 NaN
3	2	0.0	 1.0

df.sort_values(by=['B'], inplace=True)
df
>>> 
	A	B	 C
3	2	0.0	 1.0
0	1	2.0	 3.0
2	3	4.0	 NaN
1	5	NaN	 5.0

df.sort_values(by=['B'], inplace=True, na_position='first')
df
>>> 
	A	B	 C
1	5	NaN	 5.0
3	2	0.0	 1.0
0	1	2.0	 3.0
2	3	4.0	 NaN

(7) math.nan和np.nan

math.py源码

代码示例

np.nan is np.nan
>>> True
np.nan == np.nan
>>> False
math.nan is math.nan
>>> True
math.nan == math.nan
>>> False
np.nan is math.nan
>>> False
np.nan == math.nan  # 两者不等
>>> False
np.isnan(math.nan)
>>> True
np.isnan(np.nan)
>>> True
type(math.nan)
>>> float
type(np.nan)
>>> float
math.isnan(-1000000000000000000000.11)
>>> False
np.isnan(-10000000000000000000000.11)
>>> False

2、pd.isnull == pd.isna

(1) 有趣的现象

先看下面几行代码:

pd.isnull
>>> <function pandas.core.dtypes.missing.isna(obj)>
pd.isna
>>> <function pandas.core.dtypes.missing.isna(obj)>
pd.isnull == pd.isna
>>> True

为什么?

(2) 原因

首先看pandas 0.21版本的改变,官方文档原文如下:

In order to promote more consistency among the pandas API, we have
added additional top-level functions isna() and notna() that are
aliases for isnull() and notnull(). The naming scheme is now more
consistent with methods like .dropna() and .fillna(). Furthermore in
all cases where .isnull() and .notnull() methods are defined, these
have additional methods named .isna() and .notna(), these are included
for classes Categorical, Index, Series, and DataFrame. (GH15001).
The configuration option pd.options.mode.use_inf_as_null is deprecated,
and pd.options.mode. use_inf_as_na is added as a replacement.

官方文档已经说的很清楚,isna()和notna()是isnull()和notnull()的别名,它们的用法是一样的。
注意:在pandas 0.21之前的版本中是没有isna和notna的,如果pandas版本是之前的老版本,会报错AttributeError: module ‘pandas‘ has no attribute ‘isna‘
需要pip install --upgrade pandas 一下即可。具体可点击链接查看。

再看一些其他资料:
缺省值判断 pd.isnull, pd.isna, pd.notna, pd.notnull, np.isnan, math.isnan 区别_第1张图片
那么,为什么用两个名称不同的方法做相同的事情?

  1. pandas的DataFrame数据类型基于R的DataFrame数据类型,在R语言中,na和null是两种不同的东西,两个类型是分开的。
    (1) null 表示R中的空对象
    (2) NA 表示R中长度为1的逻辑常数,即NA是一个逻辑值,表示逻辑不确定值的结果。
    R中的NA与NULL: https://www.r-bloggers.com/r-na-vs-null/
  2. 同时pandas也是基于numpy,它是构建在numpy之上的。在numpy中,既没有na也没有null,而只有NaN (意思是“Not a Number”),因此,pandas也沿用NaN值。所以造成了isna和isnull两个名称不同但功能相同的情况。
    pandas的isna 、isnull源码: https://github.com/pandas-dev/pandas/blob/master/pandas/core/dtypes/missing.py

简单的说:

  • numpy用isnan()检查是否存在NaN。
  • pandas用isna()或者isnull()检查是否存在NaN。
  • 存在着两种方法,只是因为pandas对R的模仿。

NULL represents the null object in R: it is a reserved word. NULL is
often returned by expressions and functions whose values are
undefined.

NA is a logical constant of length 1 which contains a missing value
indicator. NA can be freely coerced to any other vector type except
raw. There are also constants NA_integer_, NA_real_, NA_complex_ and
NA_character_ of the other atomic vector types which support missing
values: all of these are reserved words in the R language.

3、注意pd.DataFrame.isna() 和pd.isna()

1、区别

  • pd.DataFrame.isna(obj) 和pd.DataFrame.isnull(obj)的参数只能是DataFrame;
  • pd.Series.isna(obj) 和pd.Series.isnull(obj)的参数只能是Series;
  • pd.isna(obj)和pd.isnull(obj)的参数可以是DataFrame、Series、字符串、list、index等各种类型。

2、代码示例

df_f = pd.DataFrame({
     'A':[1,3,np.nan],'B':[2,4,np.nan],'C':[3,5,np.nan]})
df_f
>>> 
	A	B	C
0	1.0	2.0	3.0
1	3.0	4.0	5.0
2	NaN	NaN	NaN

pd.DataFrame.isna(df_f)
>>> 
	A	    B	    C
0	False	False	False
1	False	False	False
2	True	True	True

pd.isna(df_f)
>>> 
	A	    B	    C
0	False	False	False
1	False	False	False
2	True	True	True

df_f.isna()
>>> 
	A	B	C
0	False	False	False
1	False	False	False
2	True	True	True

pd.DataFrame.isna('dog')  # 报类型错误,参数要求是DataFrame类型
>>> TypeError: super(type, obj): obj must be an instance or subtype of type

pd.isna('dog')
>>> False

pd.isna('')
>>> False

pd.isna([])
>>> array([], dtype=bool)

pd.isna([np.nan, 1, 3])
>>> array([ True, False, False])

index = pd.DatetimeIndex(["2017-07-05", "2017-07-06", None,"2017-07-08"])
index
>>> DatetimeIndex(['2017-07-05', '2017-07-06', 'NaT', '2017-07-08'], dtype='datetime64[ns]', freq=None)
pd.isna(index)
>>> array([False, False,  True, False])

pd.isna(None)
>>> True

pd.isna(np.nan)
>>> True

你可能感兴趣的:(Python,Numpy,Pandas,python)