在 Cython 中,有与 NumPy 相对应的编译时类型。看起来编译时类型比原始类型更快。如果我们将它们与 C 类型结合起来,例如,可以使用三个关键字来定义整数类型:
int
、np.int
、np.int_t
。
在官方教程中,都使用了这三种类型。这让我感到很困惑。这是我的问题:
使用单一数据类型来获得更好的性能是否正确?还有,我应该选择哪种类型?如果使用单一数据类型不正确,那么我应该如何确定在程序的不同部分使用哪种类型?
看来这个教程已经非常过时了。 NumPy 没有
int_t
,并且 int
已弃用(np.int
,而不是 int
)。
所以我想这回答了使用哪个 int 选项的问题。只有
int
,默认为 np.int64
(至少在我的机器上,也可能是 np.int32
)。
但是,请注意,
int
有不同的大小选项,例如 int32
和 int64
,如果您知道要存储的整数的大小,则可以在其中进行选择。
不幸的是,另一个答案部分正确,并且 Cython 文档看起来不幸部分已经过时。
因此,本质上有两种情况可以将 Numpy 类型与 Cython 结合使用:
这些 Python 对象可以作为
dtype=
参数传递给 Numpy 函数。这些向 Numpy 指示要创建什么类型的数组。从 Cython 的角度来看,它们与任何其他 Python 对象相同。然而,Numpy 将它们视为特殊指标。 np.int
就是其中的一个示例(但现在已被删除,转而只使用普通的 Python int
)。不过,像 np.int32
这样的特定大小的整数数据类型仍然可用。
arr = np.zeros((5,10), dtype=np.int)
这些不是 Cython 特定的。它们与您在普通 Python 代码中使用的相同。
第二种用途是作为 C 整数类型。
np.int_t
确实存在(这是另一个答案错误的地方)。但是,它是一个 C typedef,仅在包装 Cython 的 Numpy 内部结构的 .pxd 文件中公开。它们是您从 Numpy cimport
得到的,而不是您从 Numpy import
得到的。
您可以在需要 C 类型的任何地方使用这些类型(例如
cdef int_t some_var
或 cdef int_t[:] some_memoryview
)。它们基本上与 dtypes
具有相同的名称,但末尾带有 _t
。
作为如何将两者结合起来的示例,您可以创建一个 2D 内存视图,并为其分配一个数组以使用该行进行查看
cdef np.int32_t[:,:] mview = np.zeros((5, 10), dtype=np.int32)
普通的
int
类型在 Cython 中有两种含义。它可以用作普通的 Python 整数对象(例如,您可以将其作为 dtype
参数传递)。然而,在其他上下文中,Python 将其解释为 C 整数。因此你可以这样做
cdef int[:,:] mview = np.zeros((5, 10), dtype=int)
这也行得通。第一次使用它作为 C 类型。第二个是普通的 Python 对象。
这有点令人困惑,因为 Cython 跨越了 Python(其中类型只是 Python 对象,就像任何其他 Python 对象一样)和 C(其中类型用于声明变量,但不是本身要传递的对象)并且它并不总是清楚哪些位类似于 C,哪些位类似于 Python。