Diferencia entre np.int, np.int, int, y np.int ¿t en cython?
Tengo problemas con tantos tipos de datos int
en cython.
np.int, np.int_, np.int_t, int
Supongo que int
en python puro es equivalente a np.int_
, entonces ¿de dónde viene np.int
? No puedo encontrar el documento de numpy? Además, ¿por qué existe np.int_
dado que ya tenemos int
?
En cython, supongo que int
se convierte en un tipo C cuando se usa como cdef int
o ndarray[int]
, y cuando se usa como int()
se queda como el lanzador de python?
Es np.int_
equivalente a long
en C? así que cdef long
es el idéntica a cdef np.int_
?
¿En qué circunstancias debo usar np.int_t
en lugar de np.int
? e. g.cdef np.int_t
, ndarray[np.int_t]
...
¿Puede alguien explicar brevemente cómo el uso incorrecto de esos tipos afectaría el rendimiento del código compilado de cython?
2 answers
Es un poco complicado porque los nombres tienen diferentes significados dependiendo del contexto.
int
-
En Python
El
int
normalmente es solo un tipo Python, es de precisión arbitraria, lo que significa que puede almacenar cualquier entero concebible dentro de él (siempre y cuando tenga suficiente memoria).>>> int(10**50) 100000000000000000000000000000000000000000000000000
-
Sin embargo, cuando se utiliza como
dtype
para una matriz NumPy se interpretará comonp.int_
1. Que es no de precisión arbitraria, tendrá el mismo tamaño que Clong
:>>> np.array(10**50, dtype=int) OverflowError: Python int too large to convert to C long
Eso también significa que los dos siguientes son equivalentes:{[55]]}
np.array([1,2,3], dtype=int) np.array([1,2,3], dtype=np.int_)
-
Como identificador de tipo Cython tiene otro significado, aquí representa el c tipo
int
. Es de precisión limitada (típicamente 32bits). Puede usarlo como tipo Cython, por ejemplo al definir variables concdef
:cdef int value = 100 # variable cdef int[:] arr = ... # memoryview
Como valor de retorno o valor de argumento para
cdef
ocpdef
funciones:cdef int my_function(int argument1, int argument2): # ...
Como "genérico" para
ndarray
:cimport numpy as cnp cdef cnp.ndarray[int, ndim=1] val = ...
Para el tipo de fundición:
avalue = <int>(another_value)
Y probablemente muchos más.
-
En Cython pero como tipo Python. Todavía puedes llamar a
int
y obtendrás un "Python int" (de precisión arbitraria), o usarlo paraisinstance
o como argumentodtype
paranp.array
. Aquí el contexto es importante, por lo que convertir a Pythonint
es diferente de convertir a C int:cdef object val = int(10) # Python int cdef int val = <int>(10) # C int
np.int
En realidad esto es muy fácil. Es solo un alias para int
:
>>> int is np.int
True
Así que todo lo de arriba se aplica a np.int
también. Sin embargo, no se puede utilizar como un identificador de tipo, excepto cuando se utiliza en el paquete ed cimport
. En ese caso representa el tipo entero de Python.
cimport numpy as cnp
cpdef func(cnp.int obj):
return obj
Esto esperará que obj
sea un entero Python no un tipo NumPy :
>>> func(np.int_(10))
TypeError: Argument 'obj' has incorrect type (expected int, got numpy.int32)
>>> func(10)
10
Mi consejo con respecto a np.int
: Evítalo siempre que sea posible. En código Python es equivalente a int
y en Cython código también es equivalente a Pythons int
pero si se usa como identificador de tipo, probablemente te confundirá a ti y a todos los que lean el código. Ciertamente me confundió...
np.int_
En realidad solo tiene un significado: Es un tipo Python que representa un tipo NumPy escalar. Lo usas como Pitones int
: {[55]]}
>>> np.int_(10) # looks like a normal Python integer
10
>>> type(np.int_(10)) # but isn't (output may vary depending on your system!)
numpy.int32
O lo usa para especificar el dtype
, por ejemplo con np.array
:
>>> np.array([1,2,3], dtype=np.int_)
array([1, 2, 3])
Pero no puede usarlo como identificador de tipo en Cython.
cnp.int_t
Es la versión del identificador de tipo para np.int_
. Eso significa que no puedes usarlo como argumento dtype. Pero puede usarlo como tipo para las declaraciones cdef
:
cimport numpy as cnp
import numpy as np
cdef cnp.int_t[:] arr = np.array([1,2,3], dtype=np.int_)
|---TYPE---| |---DTYPE---|
Este ejemplo (con suerte) muestra que el identificador de tipo con el final _t
en realidad representa el tipo de una matriz que utiliza el dtype sin el final t
. ¡No puedes intercambiarlos en código Cython!
Notas
Hay varios tipos numéricos en NumPy incluiré una lista que contiene el dtype NumPy y el identificador de tipo Cython y el identificador de tipo C que también se podría usar en Cython aquí. Pero básicamente está tomado de la documentación de NumPy y el archivo Cython NumPy pxd
:
NumPy dtype Numpy Cython type C Cython type identifier
np.bool_ None None
np.int_ cnp.int_t long
np.intc None int
np.intp cnp.intp_t ssize_t
np.int8 cnp.int8_t signed char
np.int16 cnp.int16_t signed short
np.int32 cnp.int32_t signed int
np.int64 cnp.int64_t signed long long
np.uint8 cnp.uint8_t unsigned char
np.uint16 cnp.uint16_t unsigned short
np.uint32 cnp.uint32_t unsigned int
np.uint64 cnp.uint64_t unsigned long
np.float_ cnp.float64_t double
np.float32 cnp.float32_t float
np.float64 cnp.float64_t double
np.complex_ cnp.complex128_t double complex
np.complex64 cnp.complex64_t float complex
np.complex128 cnp.complex128_t double complex
En realidad hay tipos de citones para np.bool_
: cnp.npy_bool
y bint
pero ambos no se pueden usar para matrices NumPy actualmente. Para los escalares cnp.npy_bool
solo será un entero sin signo mientras que bint
será un booleano. No estoy seguro qué está pasando ahí...
1 Tomado de la documentación de NumPy"Data type objects"
Tipos de Python integrados
Varios tipos de python son equivalentes a un escalar de matriz correspondiente cuando se usan para generar un objeto dtype:
int np.int_ bool np.bool_ float np.float_ complex np.cfloat bytes np.bytes_ str np.bytes_ (Python2) or np.unicode_ (Python3) unicode np.unicode_ buffer np.void (all others) np.object_
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-26 00:57:07
np.int_
es el tipo entero predeterminado ( como se define en NumPy docs), en un sistema de 64 bits esto sería un C long
. np.intc
es el valor predeterminado C int
ya sea int32
o int64
. {[7] } es un alias de la función incorporada int
>>> np.int(2.4)
2
>>> np.int is int # object id equality
True
Los tipos de datos de cython deben reflejar C
tipos de datos, por lo que cdef int a
es un C int
y así sucesivamente.
En cuanto a np.int_t
que es el Cython
equivalente en tiempo de compilación del tipo de datos NumPy np.int_
, np.int64_t
es el Cython
equivalente en tiempo de compilación de np.int64
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-18 12:35:54