How can one reliably determine if an object has a numpy type?
I realize that this question goes against the philosophy of duck typing, but idea is to make sure a fun
Use the builtin type
function to get the type, then you can use the __module__
property to find out where it was defined:
>>> 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
That actually depends on what you're looking for.
ndarray
, a isinstance(..., np.ndarray)
is probably the easiest. Make sure you don't reload numpy in the background as the module may be different, but otherwise, you should be OK. MaskedArrays
, matrix
, recarray
are all subclasses of ndarray
, so you should be set.shape
and a dtype
attribute. You can compare its dtype
to the basic dtypes, whose list you can find in np.core.numerictypes.genericTypeRank
. Note that the elements of this list are strings, so you'd have to do a tested.dtype is np.dtype(an_element_of_the_list)
...Note that the type(numpy.ndarray)
is a type
itself and watch out for boolean and scalar types. Don't be too discouraged if it's not intuitive or easy, it's a pain at first.
See also: - https://docs.scipy.org/doc/numpy-1.15.1/reference/arrays.dtypes.html - 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
Fun with booleans:
>>> 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
More fun with scalar types, see: - 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!
To get the type, use the builtin type
function. With the in
operator, you can test if the type is a numpy type by checking if it contains the string 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
(This example was run in IPython, by the way. Very handy for interactive use and quick tests.)
The solution I've come up with is:
isinstance(y, (np.ndarray, np.generic) )
However, it's not 100% clear that all numpy types are guaranteed to be either np.ndarray
or np.generic
, and this probably isn't version robust.
Old question but I came up with a definitive answer with an example. Can't hurt to keep questions fresh as I had this same problem and didn't find a clear answer. The key is to make sure you have numpy
imported, and then run the isinstance
bool. While this may seem simple, if you are doing some computations across different data types, this small check can serve as a quick test before your start some numpy vectorized operation.
##################
# important part!
##################
import numpy as np
####################
# toy array for demo
####################
arr = np.asarray(range(1,100,2))
########################
# The instance check
########################
isinstance(arr,np.ndarray)