如何识别 python 中的 numpy 类型?

如何可靠地确定一个对象是否有一个数字类型?

我意识到这个问题违背了 Duck 类型化的原理,但是我的想法是确保一个函数(使用 scypy 和 numpy)永远不会返回 numpy 类型,除非它是用 numpy 类型调用的。但是我认为确定一个对象是否有一个 numpy 类型的一般问题与最初的问题相去甚远,应该把它们分开。

178117 次浏览

我想到的解决办法是:

isinstance(y, (np.ndarray, np.generic) )

但是,保证所有数字类型都是 np.ndarraynp.generic还不是百分之百清楚,这可能不是版本健壮的。

要获得类型,请使用内置的 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函数来获取类型,然后您可以使用 __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

这其实取决于你要找什么。

  • 如果你想测试一个序列是否实际上是一个 ndarray,一个 isinstance(..., np.ndarray)可能是最简单的。确保不要在后台重新加载 numpy,因为模块可能不同,但是否则,应该没问题。MaskedArraysmatrixrecarray都是 ndarray的子类,所以应该设置。
  • 如果您想测试一个标量是否是一个数字标量,那么事情就会变得有点复杂。您可以检查它是否具有 shapedtype属性。您可以将其 dtype与基本 dtype 进行比较,您可以在 np.core.numerictypes.genericTypeRank中找到它们的列表。请注意,这个列表的元素是字符串,因此您必须执行 tested.dtype is np.dtype(an_element_of_the_list)..。

这是个老问题了,但我用一个例子给出了一个明确的答案。让问题保持新鲜也无妨,因为我也有同样的问题,而且没有找到明确的答案。关键是确保导入了 numpy,然后运行 isinstance bool。虽然这看起来很简单,但是如果您正在跨不同的数据类型进行一些计算,那么这个小检查可以在您开始一些麻烦的向量化操作之前作为一个快速测试。

##################
# important part!
##################


import numpy as np


####################
# toy array for demo
####################


arr = np.asarray(range(1,100,2))


########################
# The instance check
########################


isinstance(arr,np.ndarray)

请注意,type(numpy.ndarray)本身就是 type,请注意布尔类型和标量类型。不要太沮丧,如果它不是直觉或容易,这是一个痛苦在第一。

参见: https://docs.scipy.org/doc/numpy-1.15.1/reference/arrays.dtypes.html 译自: 美国《科学》杂志网站(href = “ https://github.com/machinalis/mypy-data/tree/master/numpy-mypy”rel = “ norefrer”) https://github.com/machinalis/mypy-data/tree/master/numpy-mypy

>>> 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

标量类型更有趣,参见: - < a href = “ https://docs.scipy.org/doc/numpy-1.15.1/reference/arrays.scalars.html # array-scalars-build-in”rel = “ norefrer”> 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!