Difference between np.int, np.int_, int, and np.int_t in cython? Difference between np.int, np.int_, int, and np.int_t in cython? numpy numpy

Difference between np.int, np.int_, int, and np.int_t in cython?


It's a bit complicated because the names have different meanings depending on the context.

int

  1. In Python

    The int is normally just a Python type, it's of arbitrary precision, meaning that you can store any conceivable integer inside it (as long as you have enough memory).

    >>> int(10**50)100000000000000000000000000000000000000000000000000
  2. However, when you use it as dtype for a NumPy array it will be interpreted as np.int_ 1. Which is not of arbitrary precision, it will have the same size as C's long:

    >>> np.array(10**50, dtype=int)OverflowError: Python int too large to convert to C long

    That also means the following two are equivalent:

    np.array([1,2,3], dtype=int)np.array([1,2,3], dtype=np.int_)
  3. As Cython type identifier it has another meaning, here it stands for the type int. It's of limited precision (typically 32bits). You can use it as Cython type, for example when defining variables with cdef:

    cdef int value = 100    # variablecdef int[:] arr = ...   # memoryview

    As return value or argument value for cdef or cpdef functions:

    cdef int my_function(int argument1, int argument2):    # ...

    As "generic" for ndarray:

    cimport numpy as cnpcdef cnp.ndarray[int, ndim=1] val = ...

    For type casting:

    avalue = <int>(another_value)

    And probably many more.

  4. In Cython but as Python type. You can still call int and you'll get a "Python int" (of arbitrary precision), or use it for isinstance or as dtype argument for np.array. Here the context is important, so converting to a Python int is different from converting to a C int:

    cdef object val = int(10)  # Python intcdef int val = <int>(10)   # C int

np.int

Actually this is very easy. It's just an alias for int:

>>> int is np.intTrue

So everything from above applies to np.int as well. However you can't use it as a type-identifier except when you use it on the cimported package. In that case it represents the Python integer type.

cimport numpy as cnpcpdef func(cnp.int obj):    return obj

This will expect obj to be a Python integer not a NumPy type:

>>> func(np.int_(10))TypeError: Argument 'obj' has incorrect type (expected int, got numpy.int32)>>> func(10)10

My advise regarding np.int: Avoid it whenever possible. In Python code it's equivalent to int and in Cython code it's also equivalent to Pythons int but if used as type-identifier it will probably confuse you and everyone who reads the code! It certainly confused me...

np.int_

Actually it only has one meaning: It's a Python type that represents a scalar NumPy type. You use it like Pythons int:

>>> np.int_(10)        # looks like a normal Python integer10>>> type(np.int_(10))  # but isn't (output may vary depending on your system!)numpy.int32

Or you use it to specify the dtype, for example with np.array:

>>> np.array([1,2,3], dtype=np.int_)array([1, 2, 3])

But you cannot use it as type-identifier in Cython.

cnp.int_t

It's the type-identifier version for np.int_. That means you can't use it as dtype argument. But you can use it as type for cdef declarations:

cimport numpy as cnpimport numpy as npcdef cnp.int_t[:] arr = np.array([1,2,3], dtype=np.int_)     |---TYPE---|                         |---DTYPE---|

This example (hopefully) shows that the type-identifier with the trailing _t actually represents the type of an array using the dtype without the trailing t. You can't interchange them in Cython code!

Notes

There are several more numeric types in NumPy I'll include a list containing the NumPy dtype and Cython type-identifier and the C type identifier that could also be used in Cython here. But it's basically taken from the NumPy documentation and the Cython NumPy pxd file:

NumPy dtype          Numpy Cython type         C Cython type identifiernp.bool_             None                      Nonenp.int_              cnp.int_t                 longnp.intc              None                      int       np.intp              cnp.intp_t                ssize_tnp.int8              cnp.int8_t                signed charnp.int16             cnp.int16_t               signed shortnp.int32             cnp.int32_t               signed intnp.int64             cnp.int64_t               signed long longnp.uint8             cnp.uint8_t               unsigned charnp.uint16            cnp.uint16_t              unsigned shortnp.uint32            cnp.uint32_t              unsigned intnp.uint64            cnp.uint64_t              unsigned longnp.float_            cnp.float64_t             doublenp.float32           cnp.float32_t             floatnp.float64           cnp.float64_t             doublenp.complex_          cnp.complex128_t          double complexnp.complex64         cnp.complex64_t           float complexnp.complex128        cnp.complex128_t          double complex

Actually there are Cython types for np.bool_: cnp.npy_bool and bint but both they can't be used for NumPy arrays currently. For scalars cnp.npy_bool will just be an unsigned integer while bint will be a boolean. Not sure what's going on there...


1 Taken From the NumPy documentation "Data type objects"

Built-in Python types

Several python types are equivalent to a corresponding array scalar when used to generate a dtype object:

int           np.int_bool          np.bool_float         np.float_complex       np.cfloatbytes         np.bytes_str           np.bytes_ (Python2) or np.unicode_ (Python3)unicode       np.unicode_buffer        np.void(all others)  np.object_


np.int_ is the default integer type (as defined in the NumPy docs), on a 64bit system this would be a C long. np.intc is the default C int either int32 or int64. np.int is an alias to the built-in int function

>>> np.int(2.4)2>>> np.int is int  # object id equalityTrue

The cython datatypes should reflect C datatypes, so cdef int a is a C int and so on.

As for np.int_t that is the Cython compile time equivalent of the NumPy np.int_ datatype, np.int64_t is the Cython compile time equivalent of np.int64