当前位置: 首页 > 面试题库 >

cython中的np.int,np.int_,int和np.int_t之间的区别?

冀越
2023-03-14
问题内容

intcython中的这么多数据类型让我有些挣扎。

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_tndarray[np.int_t]

有人可以简要解释一下这些类型的错误使用将如何影响已编译cython代码的性能吗?


问题答案:

这有点复杂,因为名称根据上下文具有不同的含义。

  1. 在Python中

int通常仅仅是一个Python类型,它是任意精度的,这意味着你可以存储在它里面的任何可能的整数(只要你有足够的内存)。

    >>> int(10**50)
100000000000000000000000000000000000000000000000000
  1. 但是,当将其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_)
  1. 作为Cython类型标识符,它还有另一个含义,在这里代表ctype int。它的精度有限(通常为32位)。您可以将其用作Cython类型,例如在定义变量时cdef
    cdef int value = 100    # variable
    

    cdef int[:] arr = … # memoryview

作为cdefcpdef函数返回值或参数值:

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

作为“通用” ndarray

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

对于类型转换:

    avalue = <int>(another_value)

可能还有更多。

  1. 在Cython中,但作为Python类型。您仍然可以调用,int并获得一个“ Python int”(任意精度),或者将其用作isinstance或用作的dtype参数np.array。这里的上下文很重要,因此转换为Pythonint与转换为C int是不同的:
    cdef object val = int(10)  # Python int
    

    cdef int val = (10) # C int

np.int

其实这很容易。这只是一个别名int

>>> int is np.int
True

因此,上述所有内容同样适用np.int。但是,除非在cimported软件包上使用它,否则不能将其用作类型标识符。在这种情况下,它表示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_boolbint但目前它们都不能用于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_


 类似资料:
  • 问题内容: 我最近一直在思考定义数组的两种方式之间的区别: 有区别吗? 问题答案: 它们在语义上是相同的。添加该语法只是为了帮助C程序员习惯Java。 更可取,并且不会造成混淆。

  • 问题内容: 我最近一直在思考定义数组的两种方式之间的区别: 问题答案: 它们在语义上是相同的。添加该语法只是为了帮助C程序员习惯Java。 更可取,并且不会造成混淆。

  • 问题内容: 我只是想知道为什么范围是用我的sql数据类型给出的。我定义了一个字段名称为“ id”且数据类型为“ int(2)”的表。我将值插入字段“ id”作为“ 123456”。这被接受并存储。那么给出范围的用途是什么。 提前致谢。 问题答案: 对于和其他类型,该属性仅指定显示宽度。 请参阅MySQL文档中的数字类型属性: MySQL支持扩展,可以选择在整数类型的基本关键字之后的括号中指定整数数

  • 问题内容: 今天,我的一个好朋友问我最新的Go语言和Cython之间的主要区别是什么,后者是Python的一组C扩展。我对Python的了解不多,有人可以告诉我为什么Go比Cython更好/更差吗? 问题答案: Cython并不是传统意义上的语言。它是构建Python扩展程序的预处理器,该扩展程序采用类似Python的语法(实际上,他们力求完全兼容Python)并生成C代码(使用Python C

  • 问题内容: 当我运行以下代码时,我得到了数组的地址: 但是,当我声明一个字符数组并以相同的方式打印它时,它将为我提供数组的实际内容。为什么? 问题答案: 类(即类)具有专用的方法重载,可打印char数组的字符。 对于其他数组,它没有特殊的重载,因此,当您传递时,被调用的方法是。该方法通过调用其方法将传递的对象转换为字符串。 所有数组的方法都只是从class继承的默认数组,它显示了它们的类名和默认哈

  • 问题内容: 为表定义模式之间和之间有什么区别 吗?当使用int主键时,我得到了 东西 。当整数主键,我得到表生成。有什么不同?第一个和第二个变体会产生哪些副作用? 问题答案: 更新:SQLite的ROWID列现在是64位整数: 在SQLite中,类型为INTEGER PRIMARY KEY的列是ROWID的别名(在WITHOUT ROWID表中除外),该别名始终是64位有符号整数。 所有这些都在S

  • 我在尝试Python-Selenium的XPath。 我使用这个链接来尝试教程中的一些XPath: 所以我尝试了XPaths的这两个变体。 返回9个结果 “//”如何匹配5个更多的结果?

  • 问题内容: 我有两个问题,可能需要一些帮助来理解它们。 和之间有什么区别?我知道这 意味着在单独的外壳中运行命令,然后将其传递给变量。有人可以帮助我理解这一点吗?如果我错了,请纠正我。 如果我们可以使用并且效果很好,那我为什么不能使用它呢?两者的执行周期有何不同? 问题答案: 语法是令牌级别的,因此美元符号的含义取决于其所在的令牌。表达式是现代代名词,代表命令替换;这意味着运行并将其输出放在此处。