Ответ 1
Это немного сложно, потому что имена имеют разные значения в зависимости от контекста.
int
-
В Python
int
обычно представляет собой просто тип Python, он произвольной точности, что означает, что вы можете хранить в нем любое мыслимое целое число (если у вас достаточно памяти).>>> int(10**50) 100000000000000000000000000000000000000000000000000
-
Однако, когда вы используете его как
dtype
для массива NumPy, он будет интерпретироваться какnp.int_
1. Которая не произвольной точности, она будет иметь тот же размер, что и Clong
:>>> np.array(10**50, dtype=int) OverflowError: Python int too large to convert to C long
Это также означает, что следующие два эквивалентны:
np.array([1,2,3], dtype=int) np.array([1,2,3], dtype=np.int_)
-
Как идентификатор типа Cython, он имеет другое значение, здесь он обозначает c type
int
. Он имеет ограниченную точность (обычно 32 бит). Вы можете использовать его как тип Cython, например, при определении переменных с помощьюcdef
:cdef int value = 100 # variable cdef int[:] arr = ... # memoryview
Как возвращаемое значение или значение аргумента для функций
cdef
илиcpdef
:cdef int my_function(int argument1, int argument2): # ...
Как "общий" для
ndarray
:cimport numpy as cnp cdef cnp.ndarray[int, ndim=1] val = ...
Для литья типов:
avalue = <int>(another_value)
И, возможно, еще много.
-
В Cython, но как тип Python. Вы все равно можете вызвать
int
, и вы получите "Python int" (произвольной точности) или используйте его дляisinstance
или как аргументdtype
дляnp.array
. Здесь очень важен контекст, поэтому преобразование в Pythonint
отличается от преобразования в C int:cdef object val = int(10) # Python int cdef int val = <int>(10) # C int
np.int
На самом деле это очень просто. Это просто псевдоним для int
:
>>> int is np.int
True
Итак, все вышеизложенное относится и к np.int
. Однако вы не можете использовать его как идентификатор типа, за исключением случаев, когда вы используете его в пакете cimport
ed. В этом случае он представляет собой целочисленный тип Python.
cimport numpy as cnp
cpdef func(cnp.int obj):
return obj
Ожидается, что obj
будет целым числом Python , а не типом NumPy:
>>> func(np.int_(10))
TypeError: Argument 'obj' has incorrect type (expected int, got numpy.int32)
>>> func(10)
10
Мой совет относительно np.int
: Избегайте его, когда это возможно. В коде Python он эквивалентен int
, а в коде Cython он также эквивалентен Pythons int
, но если он используется как идентификатор типа, он, вероятно, путает вас и всех, кто читает код! Это, конечно, смутило меня...
np.int_
На самом деле он имеет только одно значение: это тип Python, который представляет собой скалярный тип NumPy. Вы используете его как Pythons int
:
>>> 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
Или вы используете его для указания dtype
, например, с помощью np.array
:
>>> np.array([1,2,3], dtype=np.int_)
array([1, 2, 3])
Но вы не можете использовать его как идентификатор типа в Cython.
cnp.int_t
Это версия идентификатора типа для np.int_
. Это означает, что вы не можете использовать его как аргумент dtype. Но вы можете использовать его как тип для объявлений cdef
:
cimport numpy as cnp
import numpy as np
cdef cnp.int_t[:] arr = np.array([1,2,3], dtype=np.int_)
|---TYPE---| |---DTYPE---|
Этот пример (надеюсь) показывает, что идентификатор типа с конечным _t
фактически представляет тип массива с использованием dtype без конечного t
. Вы не можете их заменить в коде Cython!
Примечания
В NumPy есть еще несколько числовых типов. Я включу список, содержащий идентификатор типа NumPy и идентификатор типа Cython, и идентификатор типа C, который также можно использовать в Cython. Но в основном это взято из документации NumPy и файл 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
На самом деле существуют типы Cython для np.bool_
: cnp.npy_bool
и bint
, но оба они не могут использоваться для массивов NumPy в настоящее время. Для скаляров cnp.npy_bool
будет просто целое число без знака, а bint
будет логическим. Не уверен, что там происходит...
1 Взято из Документация NumPy "Объекты типа данных"
Встроенные типы Python
Несколько типов python эквивалентны соответствующему массиву массива при использовании для создания объекта 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_