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

Question:

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.

Asked By: Arcturus B

||

Answers:

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
Answered By: Mazdak

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

Answered By: Alex Riley

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

Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.