可以将数字设置为NaN或无穷大吗?
在Python中,能不能把数组中的某个元素设置为NaN
(不是一个数字)呢?
另外,能不能把一个变量设置为正无穷大或负无穷大?如果可以的话,有没有什么方法可以检查一个数字是不是无穷大呢?
5 个回答
55
可以把一个数字设置为NaN或无穷大吗?
可以的,实际上有几种方法。里面有些方法不需要额外导入库,而有些则需要用到import
。不过在这里,我只会提到标准库和NumPy(虽然NumPy不是标准库,但它是一个非常常用的第三方库)。
下面的表格总结了如何创建一个不是数字(NaN)或正负无穷大的float
:
╒══════════╤══════════════╤════════════════════╤════════════════════╕
│ result │ NaN │ Infinity │ -Infinity │
│ module │ │ │ │
╞══════════╪══════════════╪════════════════════╪════════════════════╡
│ built-in │ float("nan") │ float("inf") │ -float("inf") │
│ │ │ float("infinity") │ -float("infinity") │
│ │ │ float("+inf") │ float("-inf") │
│ │ │ float("+infinity") │ float("-infinity") │
├──────────┼──────────────┼────────────────────┼────────────────────┤
│ math │ math.nan │ math.inf │ -math.inf │
├──────────┼──────────────┼────────────────────┼────────────────────┤
│ cmath │ cmath.nan │ cmath.inf │ -cmath.inf │
├──────────┼──────────────┼────────────────────┼────────────────────┤
│ numpy │ numpy.nan │ numpy.PINF │ numpy.NINF │
│ │ numpy.NaN │ numpy.inf │ -numpy.inf │
│ │ numpy.NAN │ numpy.infty │ -numpy.infty │
│ │ │ numpy.Inf │ -numpy.Inf │
│ │ │ numpy.Infinity │ -numpy.Infinity │
╘══════════╧══════════════╧════════════════════╧════════════════════╛
关于这个表格有几点说明:
float
构造函数其实不区分大小写,所以你也可以用float("NaN")
或float("InFiNiTy")
。cmath
和numpy
的常量返回的是普通的Pythonfloat
对象。numpy.NINF
是我知道的唯一一个不需要-
的常量。可以用
complex
和cmath
创建复杂的NaN和无穷大:╒══════════╤════════════════╤═════════════════╤═════════════════════╤══════════════════════╕ │ result │ NaN+0j │ 0+NaNj │ Inf+0j │ 0+Infj │ │ module │ │ │ │ │ ╞══════════╪════════════════╪═════════════════╪═════════════════════╪══════════════════════╡ │ built-in │ complex("nan") │ complex("nanj") │ complex("inf") │ complex("infj") │ │ │ │ │ complex("infinity") │ complex("infinityj") │ ├──────────┼────────────────┼─────────────────┼─────────────────────┼──────────────────────┤ │ cmath │ cmath.nan ¹ │ cmath.nanj │ cmath.inf ¹ │ cmath.infj │ ╘══════════╧════════════════╧═════════════════╧═════════════════════╧══════════════════════╛
带有¹的选项返回的是普通的
float
,而不是complex
。
有没有函数可以检查一个数字是否是无穷大?
有的,实际上有几个函数可以用来检查NaN、无穷大,或者既不是NaN也不是无穷大。不过这些预定义的函数不是内置的,使用时总是需要import
:
╒══════════╤═════════════╤════════════════╤════════════════════╕
│ for │ NaN │ Infinity or │ not NaN and │
│ │ │ -Infinity │ not Infinity and │
│ module │ │ │ not -Infinity │
╞══════════╪═════════════╪════════════════╪════════════════════╡
│ math │ math.isnan │ math.isinf │ math.isfinite │
├──────────┼─────────────┼────────────────┼────────────────────┤
│ cmath │ cmath.isnan │ cmath.isinf │ cmath.isfinite │
├──────────┼─────────────┼────────────────┼────────────────────┤
│ numpy │ numpy.isnan │ numpy.isinf │ numpy.isfinite │
╘══════════╧═════════════╧════════════════╧════════════════════╛
再说几句:
cmath
和numpy
的函数也适用于复杂对象,它们会检查实部或虚部是否是NaN或无穷大。numpy
的函数也适用于numpy
数组以及可以转换为数组的其他类型(比如列表、元组等)。- NumPy还有一些函数可以明确检查正负无穷大:
numpy.isposinf
和numpy.isneginf
。 - Pandas提供了两个额外的函数来检查
NaN
:pandas.isna
和pandas.isnull
(不过不仅仅是NaN,它还可以匹配None
和NaT
) 虽然没有内置函数,但自己创建这些函数其实很简单(这里我没有考虑类型检查和文档):
def isnan(value): return value != value # NaN is not equal to anything, not even itself infinity = float("infinity") def isinf(value): return abs(value) == infinity def isfinite(value): return not (isnan(value) or isinf(value))
总结一下这些函数的预期结果(假设输入是一个float):
╒════════════════╤═══════╤════════════╤═════════════╤══════════════════╕
│ input │ NaN │ Infinity │ -Infinity │ something else │
│ function │ │ │ │ │
╞════════════════╪═══════╪════════════╪═════════════╪══════════════════╡
│ isnan │ True │ False │ False │ False │
├────────────────┼───────┼────────────┼─────────────┼──────────────────┤
│ isinf │ False │ True │ True │ False │
├────────────────┼───────┼────────────┼─────────────┼──────────────────┤
│ isfinite │ False │ False │ False │ True │
╘════════════════╧═══════╧════════════╧═════════════╧══════════════════╛
在Python中,可以把数组的一个元素设置为NaN吗?
在列表中这没问题,你可以随意放入NaN(或无穷大):
>>> [math.nan, math.inf, -math.inf, 1] # python list
[nan, inf, -inf, 1]
不过如果你想把它放入一个array
(比如array.array
或numpy.array
),那么数组的类型必须是float
或complex
,否则它会试图把它转换成数组的类型!
>>> import numpy as np
>>> float_numpy_array = np.array([0., 0., 0.], dtype=float)
>>> float_numpy_array[0] = float("nan")
>>> float_numpy_array
array([nan, 0., 0.])
>>> import array
>>> float_array = array.array('d', [0, 0, 0])
>>> float_array[0] = float("nan")
>>> float_array
array('d', [nan, 0.0, 0.0])
>>> integer_numpy_array = np.array([0, 0, 0], dtype=int)
>>> integer_numpy_array[0] = float("nan")
ValueError: cannot convert float NaN to integer
83
是的,你可以使用numpy
来实现这个功能。
import numpy as np
a = arange(3,dtype=float)
a[0] = np.nan
a[1] = np.inf
a[2] = -np.inf
a # is now [nan,inf,-inf]
np.isnan(a[0]) # True
np.isinf(a[1]) # True
np.isinf(a[2]) # True
307
使用 float()
将字符串转换为浮点数:
>>> float('NaN')
nan
>>> float('Inf')
inf
>>> -float('Inf')
-inf
>>> float('Inf') == float('Inf')
True
>>> float('Inf') == 1
False