[python] How to identify numpy types in python?

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 function (which uses scipy and numpy) never returns a numpy type unless it is called with a numpy type. This comes up in the solution to another question, but I think the general problem of determining if an object has a numpy type is far enough away from that original question that they should be separated.

This question is related to python numpy duck-typing dynamic-typing

The answer is


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)

That actually depends on what you're looking for.

  • If you want to test whether a sequence is actually a 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.
  • If you want to test whether a scalar is a numpy scalar, things get a bit more complicated. You could check whether it has a 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)...

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


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!

Examples related to python

programming a servo thru a barometer Is there a way to view two blocks of code from the same file simultaneously in Sublime Text? python variable NameError Why my regexp for hyphenated words doesn't work? Comparing a variable with a string python not working when redirecting from bash script is it possible to add colors to python output? Get Public URL for File - Google Cloud Storage - App Engine (Python) Real time face detection OpenCV, Python xlrd.biffh.XLRDError: Excel xlsx file; not supported Could not load dynamic library 'cudart64_101.dll' on tensorflow CPU-only installation

Examples related to numpy

Unable to allocate array with shape and data type How to fix 'Object arrays cannot be loaded when allow_pickle=False' for imdb.load_data() function? Numpy, multiply array with scalar TypeError: only integer scalar arrays can be converted to a scalar index with 1D numpy indices array Could not install packages due to a "Environment error :[error 13]: permission denied : 'usr/local/bin/f2py'" Pytorch tensor to numpy array Numpy Resize/Rescale Image what does numpy ndarray shape do? How to round a numpy array? numpy array TypeError: only integer scalar arrays can be converted to a scalar index

Examples related to duck-typing

What is the right way to treat argparse.Namespace() as a dictionary? How to identify numpy types in python? What is duck typing?

Examples related to dynamic-typing

How to identify numpy types in python? What is the difference between statically typed and dynamically typed languages?