NaN和None有什么区别?

151
我正在使用pandas的read_csv()方法读取csv文件的两列,并将值分配给一个字典,这些列包含数字和字母的字符串。偶尔会出现单元格为空的情况。在我看来,应该将空单元格读入的字典条目的值设为None,但实际上被赋予了nan。显然,None更能描述一个空单元格,因为它具有null值,而nan只是说明所读取的值不是数字。

我的理解是否正确?Nonenan之间有什么区别?为什么使用nan而不是None?此外,我的字典检查是否有空单元格一直使用的是numpy.isnan()

for k, v in my_dict.iteritems():
    if np.isnan(v):

但是这会给我一个错误,说我不能对v使用此检查。我猜这是因为应该使用整数或浮点变量,而不是字符串。如果这是真的,那么我该如何检查v是否为空单元格/nan


文本“qwerty”不是一个数字。 - Robert Harvey
4
@RobertHarvey 我知道,所以“None”会更好地描述一个空单元格的值。 - user1083734
4个回答

167
NaN被用作pandas中缺失数据的占位符, 保持一致性是很好的。我通常将NaN读作"missing"。还可以在文档中查看'处理缺失数据'部分。
Wes在文档中写道'NA表示的选择':
经过多年的生产使用,至少在我看来,[NaN]是鉴于NumPy和Python的现状而做出的最佳决策。特殊值NaN(非数字)被广泛用作NA值,并且有API函数isnanotna可用于各种数据类型以检测NA值。
...
因此,我选择了Pythonic的“实用性胜过纯粹性”的方法,为了更简单地表示NA,将整数数组转换为浮点数和对象数组中的特殊值,并在需要引入NA时将整数数组提升为浮点数。注意:包含缺失数据的整数序列会被提升为浮点数。 在我看来,使用NaN(而不是None)的主要原因是它可以以numpy的float64 dtype存储,而不是效率较低的object dtype,详见NA type promotions
#  without forcing dtype it changes None to NaN!
s_bad = pd.Series([1, None], dtype=object)
s_good = pd.Series([1, np.nan])

In [13]: s_bad.dtype
Out[13]: dtype('O')

In [14]: s_good.dtype
Out[14]: dtype('float64')

Jeff对此发表了以下评论:

np.nan允许矢量化操作;它是一个浮点值,而None根据定义强制使用对象类型,这基本上禁用了numpy的所有效率。

所以快速重复3次:object==bad,float==good

话虽如此,许多操作可能在使用None和NaN时同样有效(但可能不受支持,即它们有时可能产生令人惊讶的结果):

In [15]: s_bad.sum()
Out[15]: 1

In [16]: s_good.sum()
Out[16]: 1.0

回答第二个问题:
你应该使用isnanotna来测试缺失数据(NaN)。

28
这里只是想补充一点……np.nan可以进行向量化操作,因为它是浮点数类型;而根据定义,None 强制使用“对象”类型,并且基本上会禁用 numpy 中的所有效率,所以请快速重复三遍:对象==糟糕,浮点数==好 - Jeff
4
<NA>是否也是np.nan - Gathide
1
这个问题特别涉及到pandas。这个答案很好,为什么不首先呈现?! - Guy s
这种情况的另一个陷阱是:bool(None) -> False,而 bool(float('nan')) -> True) - eltings

32

NaN可以在数学运算中作为数字值使用,而None则不能(或者至少不应该)。

NaN是一个数字值,定义在IEEE 754浮点标准中。 None是Python的内部类型(NoneType),在这个上下文中更像是“不存在”或“空”的概念,而非“数值无效”。

这主要的“症状”是,如果你对一个包含NaN的数组进行求平均或求和等计算,即使只有一个NaN,结果也会变成NaN...

另一方面,你不能将None用作操作数进行数学运算。

因此,根据情况,你可以使用None来告诉算法在计算中不考虑无效或不存在的值。这意味着算法应该测试每个值是否为None

Numpy有一些函数可以避免NaN值污染你的结果,例如nansumnan_to_num


2
我同意您的观点,即应该使用None来表示不存在的条目,那么为什么df=pd.readcsv('file.csv')会给我空单元格提供NaN值而不是None呢?据我所知,pd.DataFrames并不仅限于数字。 - user1083734
此外,许多Pandas方法都有一个na参数,它允许您决定要用哪个值来替换不可用的值。 - heltonbiker
好的,谢谢。所以我实际上并没有将数字读入我的DataFrame中,而是将数字和字母的字符串读入了其中。我应该使用什么样的检查来检测空单元格?像这样的检查;如果dtype==float:? - user1083734
也许发布一份CSV数据样本会有所帮助。我可以想象,如果有字符串,那么整个列(Series)的dtype将是字符串。但是,如果不是每行都具有相同数量的列,则可能会出现数据不可用的情况。我认为你需要检查一下。 - heltonbiker
@heltonbiker 是的,你说得对,read_csv() 会给出 NaN,但是当你读取 Excel 和 XLSB 文件时,它会给出 None。 - graj499
显示剩余4条评论

3

函数 isnan() 用于检查某个值是否为“非数字”,并返回变量是否为数字,例如 isnan(2) 将返回 false。

条件语句 myVar is not None 返回变量是否已定义。

您的 numpy 数组使用 isnan(),因为它旨在成为一个数字数组,并将数组的所有元素初始化为 NaN,这些元素被视为“空”。


1
我认为 isnan(2) 会返回 False,因为 2 不是 NaN。 - heltonbiker
另外,numpy.empty不会将数组值初始化为NaN。它根本不会初始化这些值。 - heltonbiker
5
检查变量是否为None的正确方法是使用myVar is not None,而不是myVar != None - Jaime
3
请注意,np.isnan()未实现针对字符串变量的功能,因此如果您将其传递给字符串,它将会崩溃。最好使用pd.isnull,它可以处理字符串。 - Michael

0

虽然这个链接可能回答了问题,但最好在此处包含答案的基本部分并提供参考链接。如果链接页面更改,仅有链接的答案可能会失效。- 来自审查 - A. Kootstra
@A.Kootstra 我明白。 - eswara amirthan s

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接