How to determine if a number is any type of int (core or numpy, signed or not)?

PythonNumpyTypes

Python Problem Overview


I need to test whether a variable is of type int, or any of np.int*, np.uint*, preferably using a single condition (i.e. no or).

After some tests, I guess that:

  • isinstance(n, int) will only match int and np.int32 (or np.int64 depending on plateform),
  • np.issubdtype(type(n), int) seems to match all int and np.int*, but doesn’t match np.uint*.

This leads to two questions: will np.issubdtype match any kind of signed ints? Can determine in a single check whether a number is any kind of signed or unsigned int?

This is about testing for integers, the test should return False for float-likes.

Python Solutions


Solution 1 - Python

NumPy provides base classes that you can/should use for subtype-checking, rather than the Python types.

Use np.integer to check for any instance of either signed or unsigned integers.

Use np.signedinteger and np.unsignedinteger to check for signed types or unsigned types.

>>> np.issubdtype(np.uint32, np.integer)
True
>>> np.issubdtype(np.uint32, np.signedinteger)
False
>>> np.issubdtype(int, np.integer)
True
>>> np.issubdtype(np.array([1, 2, 3]).dtype, np.integer)
True

All floating or complex number types will return False when tested.

np.issubdtype(np.uint*, int) will always be False because the Python int is a signed type.

A useful reference showing the relationship between all of these base classes is found in the documentation here.

enter image description here

Solution 2 - Python

I suggest passing a tuple of types to python isinstance() built-in function. And regarding to your question about np.issubtype() it doesn't match any kind of signed ints, it determine if a class is a subclass of a second class. And since all of integer types (int8, int32, etc.) are subclasses of int it will return True if you pass any of these type along with int.

Here is an example:

>>> a = np.array([100])
>>> 
>>> np.issubdtype(type(a[0]), int)
True
>>> isinstance(a[0], (int, np.uint))
True
>>> b = np.array([100], dtype=uint64)
>>> 
>>> isinstance(b[0], (int, np.uint))
True

Also, as a more generic approach (is not appropriate when you only want to match some specific types) you can use np.isreal():

>>> np.isreal(a[0])
True
>>> np.isreal(b[0])
True
>>> np.isreal(2.4) # This might not be the result you want
True
>>> np.isreal(2.4j)
False

Solution 3 - Python

Based on fabulous @Alex Riley answer with the tree-types I managed to solve the same problem by mapping my values to this fn. Hope it is useful for someone.

def convert_to_native_type(value):
    if isinstance(value, np.integer):
        return int(value)
    elif isinstance(value, np.float):
        return float(value)
    else:
        return value

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionArcturus BView Question on Stackoverflow
Solution 1 - PythonAlex RileyView Answer on Stackoverflow
Solution 2 - PythonMazdakView Answer on Stackoverflow
Solution 3 - PythonDavid Blanco FerrándezView Answer on Stackoverflow