int
cython中的这么多数据类型让我有些挣扎。
np.int, np.int_, np.int_t, int
我猜int
在纯python中等于np.int_
,那么它np.int
来自哪里?我无法从numpy中找到文档?另外,为什么np.int_
给定我们已经存在的存在int
?
在cython中,我猜想int
当用作cdef int
或时会变成C类型ndarray[int]
,并且当int()
它用作python
caster时会变为C类型?
是np.int_
相当于long
用C?所以cdef long
是相同cdef np.int_
?
在什么情况下我应该np.int_t
代替使用np.int
?例如cdef np.int_t
,ndarray[np.int_t]
…
有人可以简要解释一下这些类型的错误使用将如何影响已编译cython代码的性能吗?
这有点复杂,因为名称根据上下文具有不同的含义。
在int
通常仅仅是一个Python类型,它是任意精度的,这意味着你可以存储在它里面的任何可能的整数(只要你有足够的内存)。
>>> int(10**50)
100000000000000000000000000000000000000000000000000
dtype
用于NumPy数组时,它将被解释为np.int_
1。这 不是 任意精度,它将具有与C相同的大小long
:>>> 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_)
int
。它的精度有限(通常为32位)。您可以将其用作Cython类型,例如在定义变量时cdef
:cdef int value = 100 # variable
cdef int[:] arr = … # memoryview
cdef int my_function(int argument1, int argument2):
# ...
作为“通用” ndarray
:
cimport numpy as cnp
cdef cnp.ndarray[int, ndim=1] val = ...
对于类型转换:
avalue = <int>(another_value)
可能还有更多。
int
并获得一个“ Python int”(任意精度),或者将其用作isinstance
或用作的dtype
参数np.array
。这里的上下文很重要,因此转换为Pythonint
与转换为C int是不同的:cdef object val = int(10) # Python int
cdef int val =
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代码中,它等同于Python
int
;在Cython代码中,它也等同于Python,int
但是如果用作类型标识符,它可能会使您和所有阅读代码的人感到困惑!这肯定让我感到困惑。
np.int_
实际上,它只有一个含义:这是一个表示标量NumPy类型的 Python 类型。您可以像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
dtype和Cython类型标识符以及也可以在Cython中使用的C类型标识符。但这基本上来自NumPy文档和Cython
NumPypxd
文件:
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类型
当用于生成dtype对象时,几种python类型等效于对应的数组标量:
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_