如何可靠地确定对象是否具有 numpy 类型?
我意识到这个问题违背了鸭子类型的哲学,但想法是确保一个函数(使用 scipy 和 numpy)永远不会返回一个 numpy 类型,除非它被一个 numpy 类型调用。 这出现在另一个问题的解决方案中,但我认为确定对象是否具有 numpy 类型的一般问题与应该将它们分开的原始问题相距甚远。
如何可靠地确定对象是否具有 numpy 类型?
我意识到这个问题违背了鸭子类型的哲学,但想法是确保一个函数(使用 scipy 和 numpy)永远不会返回一个 numpy 类型,除非它被一个 numpy 类型调用。 这出现在另一个问题的解决方案中,但我认为确定对象是否具有 numpy 类型的一般问题与应该将它们分开的原始问题相距甚远。
使用内置type
函数获取类型,然后您可以使用__module__
属性找出它的定义位置:
>>> import numpy as np
a = np.array([1, 2, 3])
>>> type(a)
<type 'numpy.ndarray'>
>>> type(a).__module__
'numpy'
>>> type(a).__module__ == np.__name__
True
我想出的解决方案是:
isinstance(y, (np.ndarray, np.generic) )
但是,并不是 100% 清楚所有 numpy 类型都保证是np.ndarray
or np.generic
,这可能不是版本健壮的。
老问题,但我用一个例子想出了一个明确的答案。保持问题新鲜不会有什么坏处,因为我遇到了同样的问题并且没有找到明确的答案。关键是确保你已经numpy
导入,然后运行isinstance
bool。虽然这看起来很简单,但如果您正在对不同的数据类型进行一些计算,那么这个小检查可以在您开始一些 numpy 矢量化操作之前作为快速测试。
##################
# important part!
##################
import numpy as np
####################
# toy array for demo
####################
arr = np.asarray(range(1,100,2))
########################
# The instance check
########################
isinstance(arr,np.ndarray)
这实际上取决于你在寻找什么。
ndarray
, aisinstance(..., np.ndarray)
可能是最简单的。确保不要在后台重新加载 numpy,因为模块可能不同,否则,你应该没问题。MaskedArrays
, matrix
,recarray
都是 的子类ndarray
,所以应该设置。shape
和一个dtype
属性。您可以将其dtype
与基本 dtypes 进行比较,您可以在 中找到其列表np.core.numerictypes.genericTypeRank
。请注意,此列表的元素是字符串,因此您必须执行tested.dtype is np.dtype(an_element_of_the_list)
...要获取类型,请使用内置type
函数。使用in
运算符,您可以通过检查它是否包含字符串来测试该类型是否为 numpy 类型numpy
;
In [1]: import numpy as np
In [2]: a = np.array([1, 2, 3])
In [3]: type(a)
Out[3]: <type 'numpy.ndarray'>
In [4]: 'numpy' in str(type(a))
Out[4]: True
(顺便说一下,这个例子是在IPython中运行的。对于交互式使用和快速测试来说非常方便。)
请注意,它本身type(numpy.ndarray)
是 atype
并注意布尔和标量类型。如果它不直观或不简单,不要太沮丧,一开始会很痛苦。
另请参阅: - https://docs.scipy.org/doc/numpy-1.15.1/reference/arrays.dtypes.html - https://github.com/machinalis/mypy-data/tree/master/numpy-我的
>>> import numpy as np
>>> np.ndarray
<class 'numpy.ndarray'>
>>> type(np.ndarray)
<class 'type'>
>>> a = np.linspace(1,25)
>>> type(a)
<class 'numpy.ndarray'>
>>> type(a) == type(np.ndarray)
False
>>> type(a) == np.ndarray
True
>>> isinstance(a, np.ndarray)
True
布尔值的乐趣:
>>> b = a.astype('int32') == 11
>>> b[0]
False
>>> isinstance(b[0], bool)
False
>>> isinstance(b[0], np.bool)
False
>>> isinstance(b[0], np.bool_)
True
>>> isinstance(b[0], np.bool8)
True
>>> b[0].dtype == np.bool
True
>>> b[0].dtype == bool # python equivalent
True
标量类型更有趣,请参阅: - https://docs.scipy.org/doc/numpy-1.15.1/reference/arrays.scalars.html#arrays-scalars-built-in
>>> x = np.array([1,], dtype=np.uint64)
>>> x[0].dtype
dtype('uint64')
>>> isinstance(x[0], np.uint64)
True
>>> isinstance(x[0], np.integer)
True # generic integer
>>> isinstance(x[0], int)
False # but not a python int in this case
# Try matching the `kind` strings, e.g.
>>> np.dtype('bool').kind
'b'
>>> np.dtype('int64').kind
'i'
>>> np.dtype('float').kind
'f'
>>> np.dtype('half').kind
'f'
# But be weary of matching dtypes
>>> np.integer
<class 'numpy.integer'>
>>> np.dtype(np.integer)
dtype('int64')
>>> x[0].dtype == np.dtype(np.integer)
False
# Down these paths there be dragons:
# the .dtype attribute returns a kind of dtype, not a specific dtype
>>> isinstance(x[0].dtype, np.dtype)
True
>>> isinstance(x[0].dtype, np.uint64)
False
>>> isinstance(x[0].dtype, np.dtype(np.uint64))
Traceback (most recent call last):
File "<console>", line 1, in <module>
TypeError: isinstance() arg 2 must be a type or tuple of types
# yea, don't go there
>>> isinstance(x[0].dtype, np.int_)
False # again, confusing the .dtype with a specific dtype
# Inequalities can be tricky, although they might
# work sometimes, try to avoid these idioms:
>>> x[0].dtype <= np.dtype(np.uint64)
True
>>> x[0].dtype <= np.dtype(np.float)
True
>>> x[0].dtype <= np.dtype(np.half)
False # just when things were going well
>>> x[0].dtype <= np.dtype(np.float16)
False # oh boy
>>> x[0].dtype == np.int
False # ya, no luck here either
>>> x[0].dtype == np.int_
False # or here
>>> x[0].dtype == np.uint64
True # have to end on a good note!