Python:如何检查变量是一个有意义的数字类型

时间:2016-09-08 16:20:03

标签: python numpy math

在python中,如何检查变量是否为数值类型且具有有意义的值?

这里我指的是数字类型'像intfloatcomplex那些具有不同位长度和有意义值的'它不是nan或任何其他不能用于进一步计算的特殊值。

(我想这是一个很常见的问题,必须有一个重复的问题,但我没有在快速搜索后找到一个。如果有重复,请告诉我。)

4 个答案:

答案 0 :(得分:1)

>>> from math import isnan
>>> isnan(float('nan'))
True
>>> isnan(1j.real)
False
>>> isnan(1j.imag)
False

整数永远不会是NaN。

答案 1 :(得分:1)

Python 2.x和3.x

import math
import numbers

def is_numerical(x):
    return isinstance(x, numbers.Number) and not isinstance(x, bool) and not math.isnan(abs(n)) and math.isfinite(abs(n))

区别的原因是因为Python 3将longint类型合并为int

编辑:使用numbers.Number添加以下答案,以排除布尔值。

答案 2 :(得分:1)

这取决于你想要多么彻底。除了内置类型(complexfloatint)之外,还有其他类型在python中被视为数字。例如:fractions.Fractiondecimal.Decimal甚至bool都可以作为一个数字。然后,您将获得具有自己的数字类型的外部库。到目前为止,最大的是numpy。使用numpy某些类型将成功isinstance检查,而其他类型则不会。例如:isinstance(numpy.float64(10), float)为真,但isinstance(numpy.float32(10), float)不是。 除此之外,你甚至可以拥有一个用户定义的类,它就像一个数字。

Python确实提供了解决此问题的一种方法 - numbers模块。它提供了几种表示不同类型数字的抽象类型。任何实现数字功能的类都可以将自身注册为与相关类型兼容。 numbers.Number是最基本的,因此也是您正在寻找的。您所要做的就是在isinstance检查中使用它。例如

from numbers import Number
from decimal import Decimal
from fractions import Fraction
import numpy

assert isinstance(1, Number)
assert isinstance(1.5, Number)  
assert isinstance(1+5j, Number)  
assert isinstance(True, Number)

assert isinstance(Decimal("1.23"), Number)
assert isinstance(Fraction(1, 2), Number)

assert isinstance(numpy.float64(10), Number)
assert isinstance(numpy.float32(10), Number)
assert isinstance(numpy.int32(10), Number)
assert isinstance(numpy.uint32(10), Number)

这仍然让我们不知道对象是否实际上是一个数字,而不是"而不是数字"。 math.isnan函数对此有好处,但它要求数字可以转换为float(不是所有数字都是)。这里的一个大问题是complex类型。有几种方法可以解决这个问题:使用abs进行额外的isinstance检查(但这有其自身令人头疼的问题)或测试是否相等。

abs可用于每种数字类型(我能想到)。对于大多数数字,它返回数字的正数,但对于复数,它返回其数量(浮点数)。所以现在我们可以做isnan检查。 nan也是一个特殊数字,因为它是唯一与自身不相等的数字。

这意味着您的最终检查可能如下:

import math
import numbers

def number_is_not_nan(n):
    return isinstance(n, numbers.Number) and not math.isnan(abs(n))

def number_is_finite(n):
    return isinstance(n, numbers.Number) and not math.isfinite(abs(n))

答案 3 :(得分:-1)

我正在回答我自己的问题。这是基于Seth Michael Larson's answerDaveTheScientist's answer for another question。考虑到我需要小心float('inf')float('-inf')以及float('nan'),并且传递的参数x可能很复杂,我最后编写了以下函数检查。

def is_a_meaningful_number(x):
    import math
    if sys.version_info >= (3, 0, 0):
        NUMERIC_TYPES = (int, complex, float)
    else:
        NUMERIC_TYPES = (int, long, complex, float)
    return isinstance(x, NUMERIC_TYPES) and float('-inf') < abs(x) < float('inf')