21

numpy 中是否有一个现有函数可以告诉我一个值是数字类型还是 numpy 数组?我正在编写一些需要处理几种不同表示形式的数字的数据处理代码(“数字”是指可以使用标准算术运算符 +、-、*、/、* 操作的数字量的任何表示形式) *)。

我正在寻找的一些行为示例

>>> is_numeric(5)
True
>>> is_numeric(123.345)
True
>>> is_numeric('123.345')
False
>>> is_numeric(decimal.Decimal('123.345'))
True
>>> is_numeric(True)
False
>>> is_numeric([1, 2, 3])
False
>>> is_numeric([1, '2', 3])
False
>>> a = numpy.array([1, 2.3, 4.5, 6.7, 8.9])
>>> is_numeric(a)
True
>>> is_numeric(a[0])
True
>>> is_numeric(a[1])
True
>>> is_numeric(numpy.array([numpy.array([1]), numpy.array([2])])
True
>>> is_numeric(numpy.array(['1'])
False

如果不存在这样的功能,我知道写一个应该不难,比如

isinstance(n, (int, float, decimal.Decimal, numpy.number, numpy.ndarray))

但是我应该在列表中包括其他数字类型吗?

4

5 回答 5

19

正如其他人所回答的那样,除了您提到的数字类型之外,可能还有其他数字类型。一种方法是明确检查您想要的功能,例如

# Python 2
def is_numeric(obj):
    attrs = ['__add__', '__sub__', '__mul__', '__div__', '__pow__']
    return all(hasattr(obj, attr) for attr in attrs)

# Python 3
def is_numeric(obj):
    attrs = ['__add__', '__sub__', '__mul__', '__truediv__', '__pow__']
    return all(hasattr(obj, attr) for attr in attrs)

这适用于除最后一个示例之外的所有示例,numpy.array(['1']). 这是因为numpy.ndarray具有数值运算的特殊方法,但如果您尝试将它们不适当地用于字符串或对象数组,则会引发 TypeError。您可以为此添加显式检查

 ... and not (isinstance(obj, ndarray) and obj.dtype.kind in 'OSU')

这可能已经足够好了。

但是......你永远不能100%确定某人不会定义具有相同行为的另一种类型,所以更万无一失的方法是实际尝试进行计算并捕获异常,例如

def is_numeric_paranoid(obj):
    try:
        obj+obj, obj-obj, obj*obj, obj**obj, obj/obj
    except ZeroDivisionError:
        return True
    except Exception:
        return False
    else:
        return True

但取决于您计划调用使用它的频率以及使用哪些参数,这可能不实用(它可能会很慢,例如使用大型数组)。

于 2009-02-01T14:22:55.923 回答
7

此外,numpy 具有numpy.isreal和其他类似功能(numpy.is+ Tab 应该列出它们)。

他们都有自己有趣的角落案例,但其中一个可能很有用。

于 2010-01-21T01:00:35.943 回答
6

一般来说,处理未知类型的灵活、快速和 Pythonic 方法是对它们执行一些操作并捕获无效类型的异常。

try:
    a = 5+'5'
except TypeError:
    print "Oops"

在我看来,这种方法比特殊封装一些函数来确定绝对类型确定性更容易。

于 2009-02-01T07:34:44.610 回答
1

is_numeric的定义不明确。请参阅我对您的问题的评论。

其他数字类型可以是:long, complex, fractions.Fraction, numpy.bool_, numpy.ubyte, ...

operator.isNumberType()返回TruePython 数字和numpy.array.

从 Python 2.6 开始,您可以使用isinstance(d, numbers.Number)而不是 deprecated operator.isNumberType()

通常最好检查对象的功能(例如,是否可以向其添加整数)而不是其类型。

于 2009-02-01T07:31:03.383 回答
1

isinstance(numpy.int32(4), numbers.Number)Returns False,所以这不太有效。operator.isNumberType()但是,它确实适用于 numpy 数字的所有变体,包括numpy.array([1]).

于 2010-01-20T08:54:13.053 回答