数组 API#

一流智力的检验标准是能够同时在头脑中容纳两种
对立的思想,并且仍然保持
行动的能力。
F. 斯科特·菲茨杰拉德
对于一项成功的技术,现实必须优先于公共
关系,因为自然界是无法欺骗的。
理查德·P·费曼

数组结构和数据访问#

这些宏访问 PyArrayObject 结构成员,并在 ndarraytypes.h 中定义。输入参数 arr 可以是任何 PyObject*,可以直接解释为 PyArrayObject*PyArray_Type 及其子类型的任何实例)。

int PyArray_NDIM(PyArrayObject *arr)#

数组的维数。

int PyArray_FLAGS(PyArrayObject *arr)#

返回一个整数,表示 数组标志

int PyArray_TYPE(PyArrayObject *arr)#

返回此数组元素的(内置)类型编号。

int PyArray_Pack(const PyArray_Descr *descr, void *item, const PyObject *value)#

2.0 版中的新功能。

将数据类型为 descr 的内存位置 item 设置为 value

此函数等效于使用 Python 赋值设置单个数组元素。成功返回 0,失败返回 -1 并设置错误。

注意

如果 descr 设置了 NPY_NEEDS_INIT 标志,则数据必须有效或内存已清零。

int PyArray_SETITEM(PyArrayObject *arr, void *itemptr, PyObject *obj)#

转换 obj 并将其放置在 ndarray arr 中,itemptr 指向的位置。如果发生错误则返回 -1,成功则返回 0。

注意

通常,处理任意 Python 对象时,更倾向于使用 PyArray_Pack。例如,Setitem 无法处理不同数据类型之间的任意转换。

void PyArray_ENABLEFLAGS(PyArrayObject *arr, int flags)#

启用指定的数组标志。此函数不执行验证,并假定您知道自己在做什么。

void PyArray_CLEARFLAGS(PyArrayObject *arr, int flags)#

清除指定的数组标志。此函数不执行验证,并假定您知道自己在做什么。

void *PyArray_DATA(PyArrayObject *arr)#
char *PyArray_BYTES(PyArrayObject *arr)#

这两个宏类似,并获取指向数组数据缓冲区的指针。第一个宏可以(并且应该)分配给特定指针,而第二个宏用于通用处理。如果您没有保证连续和/或对齐的数组,请确保您了解如何访问数组中的数据,以避免内存和/或对齐问题。

npy_intp *PyArray_DIMS(PyArrayObject *arr)#

返回指向数组的维度/形状的指针。元素数量与数组的维度数量匹配。对于 0 维数组,可以返回 NULL

npy_intp *PyArray_SHAPE(PyArrayObject *arr)#

PyArray_DIMS 的同义词,命名与 Python 中的 shape 用法一致。

npy_intp *PyArray_STRIDES(PyArrayObject *arr)#

返回指向数组步幅的指针。元素数量与数组的维度数量匹配。

npy_intp PyArray_DIM(PyArrayObject *arr, int n)#

返回第 n 维的形状。

npy_intp PyArray_STRIDE(PyArrayObject *arr, int n)#

返回第 n 维的步长。

npy_intp PyArray_ITEMSIZE(PyArrayObject *arr)#

返回该数组元素的itemsize。

注意,在1.7版本中已弃用的旧API中,此函数的返回类型为int

npy_intp PyArray_SIZE(PyArrayObject *arr)#

返回数组的总大小(元素个数)。

npy_intp PyArray_Size(PyArrayObject *obj)#

如果 obj 不是 ndarray 的子类,则返回 0。否则,返回数组中元素的总数。这是 PyArray_SIZE (obj) 的更安全的版本。

npy_intp PyArray_NBYTES(PyArrayObject *arr)#

返回数组占用的总字节数。

PyObject *PyArray_BASE(PyArrayObject *arr)#

返回数组的基础对象。在大多数情况下,这意味着拥有数组指向的内存的对象。

如果使用C API构造数组并指定您自己的内存,则应使用函数 PyArray_SetBaseObject 将基设置为拥有内存的对象。

如果设置了 NPY_ARRAY_WRITEBACKIFCOPY 标志,则其含义不同,即基是将在复制解析时将当前数组复制到的数组。这两个函数的基属性的这种重载可能会在未来版本的 NumPy 中发生变化。

PyArray_Descr *PyArray_DESCR(PyArrayObject *arr)#

返回对数组 dtype 属性的借用引用。

PyArray_Descr *PyArray_DTYPE(PyArrayObject *arr)#

PyArray_DESCR 的同义词,命名与 Python 中的“dtype”用法保持一致。

PyObject *PyArray_GETITEM(PyArrayObject *arr, void *itemptr)#

从 ndarray arr 中获取 itemptr 指向位置的内置类型 Python 对象。失败时返回 NULL

numpy.ndarray.item 与 PyArray_GETITEM 相同。

int PyArray_FinalizeFunc(PyArrayObject *arr, PyObject *obj)#

PyCapsule __array_finalize__ 指向的函数。第一个参数是新创建的子类型。第二个参数(如果非 NULL)是“父”数组(如果数组是使用切片或其他某些操作创建的,其中存在清晰可区分的父级)。此例程可以执行任何操作。它应该在出错时返回 -1,否则返回 0。

数据访问#

这些函数和宏提供了从 C 轻松访问 ndarray 元素的方法。这些适用于所有数组。但是,如果数组不是机器字节序、未对齐或不可写,则可能需要在访问数组中的数据时小心。换句话说,除非您知道自己在做什么,或者以前使用 PyArray_FromAny 保证了可写、对齐且为机器字节序的数组,否则请务必遵守标志的状态。如果您希望处理所有类型的数组,则每种类型的 copyswap 函数对于处理行为不端的数组很有用。某些平台(例如 Solaris)不喜欢未对齐的数据,如果取消引用未对齐的指针,它们将崩溃。其他平台(例如 x86 Linux)在处理未对齐的数据时速度会变慢。

void *PyArray_GetPtr(PyArrayObject *aobj, npy_intp *ind)#

返回指向 ndarray aobj 数据的指针,该指针位于由 c 数组 ind 给出的 N 维索引处(该数组的大小必须至少为 aobj ->nd)。您可能希望将返回的指针类型转换为 ndarray 的数据类型。

void *PyArray_GETPTR1(PyArrayObject *obj, npy_intp i)#
void *PyArray_GETPTR2(PyArrayObject *obj, npy_intp i, npy_intp j)#
void *PyArray_GETPTR3(PyArrayObject *obj, npy_intp i, npy_intp j, npy_intp k)#
void *PyArray_GETPTR4(PyArrayObject *obj, npy_intp i, npy_intp j, npy_intp k, npy_intp l)#

快速内联访问ndarray obj中给定坐标处的元素,obj必须分别具有1、2、3或4个维度(不会检查)。相应的ijkl坐标可以是任何整数,但将被解释为npy_intp。您可能需要将返回的指针类型转换为ndarray的数据类型。

创建数组#

从零开始#

PyObject *PyArray_NewFromDescr(PyTypeObject *subtype, PyArray_Descr *descr, int nd, npy_intp const *dims, npy_intp const *strides, void *data, int flags, PyObject *obj)#

此函数窃取对descr的引用。最简单的获取方法是使用PyArray_DescrFromType

这是主要的数组创建函数。大多数新数组都是使用此灵活的函数创建的。

返回的对象是Python类型subtype的对象,它必须是PyArray_Type的子类型。数组具有nd个维度,由dims描述。新数组的数据类型描述符是descr

如果subtype是数组子类而不是基类&PyArray_Type,则obj是要传递给子类的__array_finalize__方法的对象。

如果dataNULL,则将分配新的未初始化内存,并且flags可以是非零值以指示Fortran样式的连续数组。使用PyArray_FILLWBYTE初始化内存。

如果data不是NULL,则假定它指向将用于数组的内存,并且flags参数用作数组的新标志(但NPY_ARRAY_OWNDATANPY_ARRAY_WRITEBACKIFCOPY标志的状态除外,新数组将被重置)。

此外,如果data非空,则也可以提供strides。如果stridesNULL,则数组步幅将计算为C样式连续(默认)或Fortran样式连续(对于data = NULLflags为非零值,或者对于非NULL的dataflags & NPY_ARRAY_F_CONTIGUOUS为非零值)。任何提供的dimsstrides都将复制到新数组对象的新分配的维度和步幅数组中。

PyArray_CheckStrides可以帮助验证非NULL步幅信息。

如果提供了data,则它必须在数组的整个生命周期中保持有效。管理此问题的一种方法是通过PyArray_SetBaseObject

PyObject *PyArray_NewLikeArray(PyArrayObject *prototype, NPY_ORDER order, PyArray_Descr *descr, int subok)#

如果descr不为NULL,此函数将窃取对descr的引用。此数组创建例程允许方便地创建一个与现有数组的形状和内存布局匹配的新数组,可能更改布局和/或数据类型。

orderNPY_ANYORDER时,如果prototype是Fortran数组,则结果顺序为NPY_FORTRANORDER,否则为NPY_CORDER。当orderNPY_KEEPORDER时,即使prototype的轴不是C或Fortran顺序,结果顺序也与prototype的顺序匹配。

如果descr为NULL,则使用prototype的数据类型。

如果subok为1,则新创建的数组将使用prototype的子类型来创建新数组,否则它将创建一个基类数组。

PyObject *PyArray_New(PyTypeObject *subtype, int nd, npy_intp const *dims, int type_num, npy_intp const *strides, void *data, int itemsize, int flags, PyObject *obj)#

这类似于 PyArray_NewFromDescr (…),除了您使用type_numitemsize指定数据类型描述符,其中type_num对应于内置(或用户定义)类型。如果类型始终具有相同数量的字节,则忽略itemsize。否则,itemsize指定此数组的特定大小。

警告

如果数据传递给 PyArray_NewFromDescrPyArray_New,则在删除新数组之前,不得释放此内存。如果此数据来自另一个Python对象,则可以使用 Py_INCREF 在该对象上增加引用计数,并将新数组的base成员设置为指向该对象。如果传入步长,则它们必须与数组的维度、itemsize和数据一致。

PyObject *PyArray_SimpleNew(int nd, npy_intp const *dims, int typenum)#

创建一个新的未初始化数组,其类型为typenum,在nd个维度中的每个维度的大小由整数数组dims给出。数组的内存未初始化(除非typenum为 NPY_OBJECT,在这种情况下,数组中的每个元素都设置为NULL)。typenum参数允许指定任何内置数据类型,例如 NPY_FLOATNPY_LONG。如果需要,可以使用 PyArray_FILLWBYTE (return_object, 0) 将数组的内存设置为零。此函数不能用于创建灵活类型数组(未给出itemsize)。

PyObject *PyArray_SimpleNewFromData(int nd, npy_intp const *dims, int typenum, void *data)#

创建一个围绕由给定指针指向的data的数组包装器。数组标志将具有一个默认值,表示数据区域行为良好且为 C 样式连续。数组的形状由长度为nddims c 数组给出。数组的数据类型由typenum指示。如果数据来自另一个引用计数的 Python 对象,则在传入指针后应增加此对象的引用计数,并且返回的 ndarray 的 base 成员应指向拥有数据的 Python 对象。这将确保在返回的数组存在时不会释放提供的内存。

PyObject *PyArray_SimpleNewFromDescr(int nd, npy_int const *dims, PyArray_Descr *descr)#

此函数窃取对descr的引用。

使用提供的数据类型描述符descr创建一个新数组,其形状由nddims确定。

void PyArray_FILLWBYTE(PyObject *obj, int val)#

val的内容(计算为字节)填充obj指向的数组——它必须是(ndarray 的)子类。此宏调用 memset,因此 obj 必须是连续的。

PyObject *PyArray_Zeros(int nd, npy_intp const *dims, PyArray_Descr *dtype, int fortran)#

构造一个新的nd维数组,其形状由dims给出,数据类型由dtype给出。如果fortran非零,则创建Fortran顺序数组,否则创建C顺序数组。用零填充内存(如果dtype对应于 NPY_OBJECT,则填充零对象)。

PyObject *PyArray_ZEROS(int nd, npy_intp const *dims, int type_num, int fortran)#

PyArray_Zeros 的宏形式,它采用类型编号而不是数据类型对象。

PyObject *PyArray_Empty(int nd, npy_intp const *dims, PyArray_Descr *dtype, int fortran)#

构造一个新的nd维数组,其形状由dims给出,数据类型由dtype给出。如果fortran非零,则创建Fortran顺序数组,否则创建C顺序数组。除非数据类型对应于 NPY_OBJECT,否则数组未初始化,在这种情况下,数组将填充 Py_None

PyObject *PyArray_EMPTY(int nd, npy_intp const *dims, int typenum, int fortran)#

这是 PyArray_Empty 的宏形式,它使用类型编号 typenum 代替数据类型对象。

PyObject *PyArray_Arange(double start, double stop, double step, int typenum)#

创建一个新的数据类型为 typenum 的一维数组,范围从 startstop(不包含 stop),步长为 step。等效于 arange(start, stop, step, dtype)。

PyObject *PyArray_ArangeObj(PyObject *start, PyObject *stop, PyObject *step, PyArray_Descr *descr)#

创建一个新的数据类型由 descr 决定的一维数组,范围从 startstop(不包含 stop),步长为 step。等效于 arange( start, stop, step, typenum )。

int PyArray_SetBaseObject(PyArrayObject *arr, PyObject *obj)#

此函数**窃取对** obj **的引用**,并将其设置为 arr 的 base 属性。

如果通过将您自己的内存缓冲区作为参数传入来构造数组,则需要设置数组的 base 属性以确保内存缓冲区的生命周期适当。

成功返回 0,失败返回 -1。

如果提供的对象是数组,此函数将遍历 base 指针链,以便每个数组都直接指向内存的所有者。设置 base 后,不能将其更改为其他值。

从其他对象#

PyObject *PyArray_FromAny(PyObject *op, PyArray_Descr *dtype, int min_depth, int max_depth, int requirements, PyObject *context)#

这是从任何嵌套序列或公开数组接口的对象 op 获取数组的主要函数。参数允许指定所需 dtype、可接受的最小 (min_depth) 和最大 (max_depth) 维数以及数组的其他 requirements。此函数**窃取对** dtype **参数的引用**,该参数需要是一个 PyArray_Descr 结构,指示所需的数据类型(包括所需的字节序)。dtype 参数可以是 NULL,表示任何数据类型(和字节序)都是可以接受的。除非 NPY_ARRAY_FORCECAST 出现在 flags 中,否则如果无法从对象安全地获取数据类型,则此调用将生成错误。如果要对 dtype 使用 NULL 并确保数组不会交换,则使用 PyArray_CheckFromAny。对于任何深度参数,值为 0 都会导致忽略该参数。可以添加以下任何数组标志(例如,使用 |)以获取 requirements 参数。如果您的代码可以处理常规(例如,跨步、字节交换或未对齐的数组),则 requirements 可以为 0。此外,如果 op 本身还不是数组(或不公开数组接口),则将创建一个新数组(并使用序列协议从 op 中填充)。新数组的 flags 成员将为 NPY_ARRAY_DEFAULTcontext 参数未使用。

NPY_ARRAY_C_CONTIGUOUS

确保返回的数组是 C 连续的。

NPY_ARRAY_F_CONTIGUOUS

确保返回的数组是 Fortran 连续的。

NPY_ARRAY_ALIGNED

确保返回的数组在其数据类型的适当边界上对齐。对齐的数组的数据指针和每个步长因子都是数据类型描述符的对齐因子的倍数。

NPY_ARRAY_WRITEABLE

确保返回的数组可以写入。

NPY_ARRAY_ENSURECOPY

确保对 op 进行复制。如果不存在此标志,则如果可以避免,则不会复制数据。

NPY_ARRAY_ENSUREARRAY

确保结果是基类 ndarray。默认情况下,如果 op 是 ndarray 子类的实例,则返回该子类的实例。如果设置此标志,则将返回 ndarray 对象。

NPY_ARRAY_FORCECAST

强制转换为输出类型,即使无法安全地进行转换也是如此。如果没有此标志,只有在可以安全地进行数据转换时才会进行数据转换,否则将引发错误。

NPY_ARRAY_WRITEBACKIFCOPY

如果 op 已经是数组,但不满足要求,则进行复制(这将满足要求)。如果存在此标志并且必须复制(对已经是数组的对象), 则在返回的副本中设置相应的 NPY_ARRAY_WRITEBACKIFCOPY 标志,并且 op 将被设置为只读。必须确保调用 PyArray_ResolveWritebackIfCopy 将内容复制回 op,并且 op 数组将再次可写。如果 op 最初不可写,或者它本身还不是数组,则会引发错误。

也可以添加 数组标志的组合

PyObject *PyArray_CheckFromAny(PyObject *op, PyArray_Descr *dtype, int min_depth, int max_depth, int requirements, PyObject *context)#

几乎与 PyArray_FromAny (…) 相同,除了 *requirements* 可以包含 NPY_ARRAY_NOTSWAPPED(覆盖 *dtype* 中的规范)和 NPY_ARRAY_ELEMENTSTRIDES,后者表示数组应以步长为元素大小的倍数的方式对齐。

PyObject *PyArray_FromArray(PyArrayObject *op, PyArray_Descr *newtype, int requirements)#

PyArray_FromAny 的特例,用于 *op* 已经是数组但需要是特定 *newtype*(包括字节序)或具有某些 *requirements* 的情况。

PyObject *PyArray_FromStructInterface(PyObject *op)#

从公开 __array_struct__ 属性并遵循数组接口协议的 Python 对象返回 ndarray 对象。如果对象不包含此属性,则返回对 Py_NotImplemented 的借用引用。

PyObject *PyArray_FromInterface(PyObject *op)#

从公开 __array_interface__ 属性并遵循数组接口协议的 Python 对象返回 ndarray 对象。如果对象不包含此属性,则返回对 Py_NotImplemented 的借用引用。

PyObject *PyArray_FromArrayAttr(PyObject *op, PyArray_Descr *dtype, PyObject *context)#

从公开 __array__ 方法的 Python 对象返回 ndarray 对象。 __array__ 的第三方实现必须采用 dtypecopy 关键字参数。context 未使用。

PyObject *PyArray_ContiguousFromAny(PyObject *op, int typenum, int min_depth, int max_depth)#

此函数从任何嵌套序列或数组接口导出对象 *op* 返回一个(C 风格)连续且行为良好的函数数组,其类型由枚举的 *typenum* 给出,最小深度为 *min_depth*,最大深度为 *max_depth*。等效于调用 PyArray_FromAny,其 requirements 设置为 NPY_ARRAY_DEFAULT,并且 type_num 成员设置为 *typenum*。

PyObject *PyArray_ContiguousFromObject(PyObject *op, int typenum, int min_depth, int max_depth)#

此函数从任何嵌套序列或数组接口导出对象返回一个行为良好的 C 风格连续数组。数组可以具有的最小维度由 min_depth 给出,最大维度由 max_depth 给出。这等效于调用 PyArray_FromAny,其 requirements 为 NPY_ARRAY_DEFAULTNPY_ARRAY_ENSUREARRAY

PyObject *PyArray_FromObject(PyObject *op, int typenum, int min_depth, int max_depth)#

从任何嵌套序列或数组接口导出对象 *op* 返回一个对齐的、采用原生字节序的数组,其类型由枚举的 *typenum* 给出。数组可以具有的最小维度由 *min_depth* 给出,最大维度由 *max_depth* 给出。这等效于调用 PyArray_FromAny,其 requirements 设置为 BEHAVED。

PyObject *PyArray_EnsureArray(PyObject *op)#

此函数**窃取对** op 的引用,并确保 op 是一个基类 ndarray。它对数组标量进行了特殊处理,否则调用 PyArray_FromAnyop, NULL, 0, 0, NPY_ARRAY_ENSUREARRAY, NULL)。

PyObject *PyArray_FromString(char *string, npy_intp slen, PyArray_Descr *dtype, npy_intp num, char *sep)#

从长度为 slen 的二进制或 (ASCII) 文本 string 构造一个单类型的一维 ndarray。要创建的数组的数据类型由 dtype 指定。如果 num 为 -1,则**复制**整个字符串并返回一个大小合适的数组;否则,num 是要从字符串中**复制**的项目数量。如果 sep 为 NULL(或“”),则将字符串解释为二进制数据的字节;否则,将由 sep 分隔的子字符串转换为数据类型 dtype 的项目。某些数据类型可能无法在文本模式下读取,如果发生这种情况,将引发错误。所有错误都返回 NULL。

PyObject *PyArray_FromFile(FILE *fp, PyArray_Descr *dtype, npy_intp num, char *sep)#

从二进制文件或文本文件构造一个单类型的一维 ndarray。打开的文件指针是 fp,要创建的数组的数据类型由 dtype 指定。这必须与文件中的数据匹配。如果 num 为 -1,则读取到文件末尾并返回一个大小合适的数组;否则,num 是要读取的项目数量。如果 sep 为 NULL(或“”),则以二进制模式从文件读取;否则,以文本模式从文件读取,sep 提供项目分隔符。某些数组类型无法在文本模式下读取,在这种情况下会引发错误。

PyObject *PyArray_FromBuffer(PyObject *buf, PyArray_Descr *dtype, npy_intp count, npy_intp offset)#

从导出(单段)缓冲区协议(或具有返回导出缓冲区协议的对象的属性 __buffer__)的对象 buf 构造一个单类型的一维 ndarray。首先将尝试使用可写缓冲区,然后是只读缓冲区。返回数组的 NPY_ARRAY_WRITEABLE 标志将反映哪个缓冲区成功。假定数据从对象的内存位置开始的 offset 字节处开始。缓冲区中数据的类型将根据数据类型描述符 dtype 进行解释。如果 count 为负,则将根据缓冲区的大小和请求的 itemsize 来确定它;否则,count 表示应从缓冲区转换多少个元素。

int PyArray_CopyInto(PyArrayObject *dest, PyArrayObject *src)#

从源数组 src 复制到目标数组 dest,如有必要,执行数据类型转换。如果发生错误,则返回 -1(否则为 0)。src 的形状必须可广播到 dest 的形状。NumPy 在复制两个数组时检查内存重叠。

int PyArray_CopyObject(PyArrayObject *dest, PyObject *src)#

根据数组强制转换规则,将对象 src 分配给 NumPy 数组 dest。这基本上与 PyArray_FromAny 相同,但直接分配给输出数组。成功返回 0,失败返回 -1。

PyArrayObject *PyArray_GETCONTIGUOUS(PyObject *op)#

如果 op 已经是(C 样式)连续且行为良好的,则只需返回一个引用;否则,返回数组的(连续且行为良好的)副本。参数 op 必须是(ndarray 的子类),并且不会对其进行检查。

PyObject *PyArray_FROM_O(PyObject *obj)#

obj 转换为 ndarray。参数可以是任何嵌套序列或导出数组接口的对象。这是 PyArray_FromAny 的宏形式,使用 NULL、0、0、0 作为其他参数。您的代码必须能够处理任何数据类型描述符和任何数据标志组合才能使用此宏。

PyObject *PyArray_FROM_OF(PyObject *obj, int requirements)#

PyArray_FROM_O类似,但它可以接受一个名为 *requirements* 的参数,用于指定结果数组必须具有的属性。可以强制执行的可用要求包括NPY_ARRAY_C_CONTIGUOUSNPY_ARRAY_F_CONTIGUOUSNPY_ARRAY_ALIGNEDNPY_ARRAY_WRITEABLENPY_ARRAY_NOTSWAPPEDNPY_ARRAY_ENSURECOPYNPY_ARRAY_WRITEBACKIFCOPYNPY_ARRAY_FORCECASTNPY_ARRAY_ENSUREARRAY。也可以使用标志的标准组合。

PyObject *PyArray_FROM_OT(PyObject *obj, int typenum)#

PyArray_FROM_O类似,但它可以接受一个名为 *typenum* 的参数,用于指定返回数组的类型编号。

PyObject *PyArray_FROM_OTF(PyObject *obj, int typenum, int requirements)#

PyArray_FROM_OFPyArray_FROM_OT的组合,允许同时提供 *typenum* 和 *flags* 参数。

PyObject *PyArray_FROMANY(PyObject *obj, int typenum, int min, int max, int requirements)#

PyArray_FromAny类似,只是数据类型是用类型编号指定的。PyArray_DescrFromType ( *typenum* ) 直接传递给PyArray_FromAny。如果将NPY_ARRAY_ENSURECOPY作为requirements传入,此宏还会将NPY_ARRAY_DEFAULT添加到requirements中。

PyObject *PyArray_CheckAxis(PyObject *obj, int *axis, int requirements)#

封装接受 axis= 关键字并能正确处理 None 作为 axis 参数的函数和方法的功能。输入数组为 obj,而 *axis 是转换后的整数(因此 *axis == NPY_RAVEL_AXIS 为 None 值),requirements 给出 obj 的所需属性。输出是输入的转换版本,以满足要求,如果需要,则会进行扁平化。在输出时,*axis 的负值将被转换,并检查新值以确保与 obj 的形状一致。

处理类型#

Python类型的常规检查#

int PyArray_Check(PyObject *op)#

如果 *op* 是一个 Python 对象,其类型是 PyArray_Type 的子类型,则评估结果为真。

int PyArray_CheckExact(PyObject *op)#

如果 *op* 是一个类型为 PyArray_Type 的 Python 对象,则评估结果为真。

int PyArray_HasArrayInterface(PyObject *op, PyObject *out)#

如果 op实现了数组接口的任何部分,则 out 将包含对使用该接口新创建的 ndarray 的新引用的,或者如果转换过程中发生错误,则 out 将包含 NULL。否则,out 将包含对 Py_NotImplemented 的借用引用,并且不会设置任何错误条件。

int PyArray_HasArrayInterfaceType(PyObject *op, PyArray_Descr *dtype, PyObject *context, PyObject *out)#

如果 op实现了数组接口的任何部分,则 out 将包含对使用该接口新创建的 ndarray 的新引用的,或者如果转换过程中发生错误,则 out 将包含 NULL。否则,out 将包含对 Py_NotImplemented 的借用引用,并且不会设置任何错误条件。此版本允许在查找 __array__ 属性的数组接口部分设置 dtype。context 未使用。

int PyArray_IsZeroDim(PyObject *op)#

如果opPyArray_Type(或其子类)的实例且维度为0,则返回真。

PyArray_IsScalar(op, cls)#

如果opPy{cls}ArrType_Type的实例,则返回真。

int PyArray_CheckScalar(PyObject *op)#

如果op是数组标量(PyGenericArrType_Type的子类型的实例)或维度为0的PyArray_Type(或其子类)的实例,则返回真。

int PyArray_IsPythonNumber(PyObject *op)#

如果op是内置数值类型的实例(int、float、complex、long、bool),则返回真。

int PyArray_IsPythonScalar(PyObject *op)#

如果op是内置Python标量对象(int、float、complex、bytes、str、long、bool),则返回真。

int PyArray_IsAnyScalar(PyObject *op)#

如果op是Python标量对象(参见PyArray_IsPythonScalar)或数组标量(PyGenericArrType_Type的子类型的实例),则返回真。

int PyArray_CheckAnyScalar(PyObject *op)#

如果op是Python标量对象(参见PyArray_IsPythonScalar)、数组标量(PyGenericArrType_Type的子类型的实例)或维度为0的PyArray_Type(或其子类)的实例,则返回真。

数据类型访问器#

某些描述符属性可能并非总是已定义,因此不应或不能直接访问。

2.0版本中的变更: 在NumPy 2.0之前,ABI不同,但对于用户DType来说过于庞大。这些访问器都添加到2.0中,并且可以向后移植(参见PyArray_Descr结构已更改)。

npy_intp PyDataType_ELSIZE(PyArray_Descr *descr)#

数据类型的元素大小(Python中的itemsize)。

注意

如果descr附加到数组,则可以使用PyArray_ITEMSIZE(arr),并且在所有NumPy版本中都可用。

void PyDataType_SET_ELSIZE(PyArray_Descr *descr, npy_intp size)#

允许设置itemsize,这仅与字符串/字节数据类型相关,因为这是定义具有新大小的字符串/字节数据类型的当前模式。

npy_intp PyDataType_ALIGNENT(PyArray_Descr *descr)#

数据类型的对齐方式。

PyObject *PyDataType_METADATA(PyArray_Descr *descr)#

附加到dtype的元数据,可以是NULL或字典。

PyObject *PyDataType_NAMES(PyArray_Descr *descr)#

NULL或附加到dtype的结构化字段名称元组。

PyObject *PyDataType_FIELDS(PyArray_Descr *descr)#

NULLNone或结构化dtype字段的字典,此字典不得更改,NumPy将来可能会更改字段的存储方式。

这与np.dtype.fields返回的字典相同。

NpyAuxData *PyDataType_C_METADATA(PyArray_Descr *descr)#

附加到描述符的C元数据对象。通常不需要此访问器。C元数据字段确实提供了对datetime/timedelta时间单位信息的访问。

PyArray_ArrayDescr *PyDataType_SUBARRAY(PyArray_Descr *descr)#

关于子数组dtype的信息,相当于Python np.dtype.basenp.dtype.shape

如果这是非NULL,则此数据类型描述符是另一个数据类型描述符的C风格连续数组。换句话说,此描述符描述的每个元素实际上都是另一个基描述符的数组。这作为另一个数据类型描述符中字段的数据类型描述符最有用。如果这是非NULL,则fields成员应为NULL(但是基描述符的fields成员可以是非NULL)。

type PyArray_ArrayDescr#
typedef struct {
    PyArray_Descr *base;
    PyObject *shape;
} PyArray_ArrayDescr;
PyArray_Descr *base#

基类型的DataType-descriptor对象。

PyObject *shape#

子数组的形状(始终为C风格连续)作为Python元组。

数据类型检查#

对于typenum宏,参数是一个整数,表示枚举数组数据类型。对于数组类型检查宏,参数必须是一个PyObject*,可以直接解释为PyArrayObject*

int PyTypeNum_ISUNSIGNED(int num)#
int PyDataType_ISUNSIGNED(PyArray_Descr *descr)#
int PyArray_ISUNSIGNED(PyArrayObject *obj)#

类型表示无符号整数。

int PyTypeNum_ISSIGNED(int num)#
int PyDataType_ISSIGNED(PyArray_Descr *descr)#
int PyArray_ISSIGNED(PyArrayObject *obj)#

类型表示有符号整数。

int PyTypeNum_ISINTEGER(int num)#
int PyDataType_ISINTEGER(PyArray_Descr *descr)#
int PyArray_ISINTEGER(PyArrayObject *obj)#

类型表示任何整数。

int PyTypeNum_ISFLOAT(int num)#
int PyDataType_ISFLOAT(PyArray_Descr *descr)#
int PyArray_ISFLOAT(PyArrayObject *obj)#

类型表示任何浮点数。

int PyTypeNum_ISCOMPLEX(int num)#
int PyDataType_ISCOMPLEX(PyArray_Descr *descr)#
int PyArray_ISCOMPLEX(PyArrayObject *obj)#

类型表示任何复数浮点数。

int PyTypeNum_ISNUMBER(int num)#
int PyDataType_ISNUMBER(PyArray_Descr *descr)#
int PyArray_ISNUMBER(PyArrayObject *obj)#

类型表示任何整数、浮点数或复数浮点数。

int PyTypeNum_ISSTRING(int num)#
int PyDataType_ISSTRING(PyArray_Descr *descr)#
int PyArray_ISSTRING(PyArrayObject *obj)#

类型表示字符串数据类型。

int PyTypeNum_ISFLEXIBLE(int num)#
int PyDataType_ISFLEXIBLE(PyArray_Descr *descr)#
int PyArray_ISFLEXIBLE(PyArrayObject *obj)#

类型表示其中一种灵活的数组类型(NPY_STRINGNPY_UNICODENPY_VOID)。

int PyDataType_ISUNSIZED(PyArray_Descr *descr)#

类型没有附加大小信息,可以调整大小。只能在灵活的dtype上调用。附加到数组的类型始终具有大小,因此此宏的数组形式不存在。

对于没有字段的结构化数据类型,此函数现在返回 False。

int PyTypeNum_ISUSERDEF(int num)#
int PyDataType_ISUSERDEF(PyArray_Descr *descr)#
int PyArray_ISUSERDEF(PyArrayObject *obj)#

类型表示用户自定义类型。

int PyTypeNum_ISEXTENDED(int num)#
int PyDataType_ISEXTENDED(PyArray_Descr *descr)#
int PyArray_ISEXTENDED(PyArrayObject *obj)#

类型是灵活的或用户自定义的。

int PyTypeNum_ISOBJECT(int num)#
int PyDataType_ISOBJECT(PyArray_Descr *descr)#
int PyArray_ISOBJECT(PyArrayObject *obj)#

类型表示对象数据类型。

int PyTypeNum_ISBOOL(int num)#
int PyDataType_ISBOOL(PyArray_Descr *descr)#
int PyArray_ISBOOL(PyArrayObject *obj)#

类型表示布尔数据类型。

int PyDataType_HASFIELDS(PyArray_Descr *descr)#
int PyArray_HASFIELDS(PyArrayObject *obj)#

类型与其关联的字段。

int PyArray_ISNOTSWAPPED(PyArrayObject *m)#

如果 ndarray m 的数据区域根据数组的数据类型描述符采用机器字节序,则评估为真。

int PyArray_ISBYTESWAPPED(PyArrayObject *m)#

如果 ndarray m 的数据区域根据数组的数据类型描述符**不**采用机器字节序,则评估为真。

npy_bool PyArray_EquivTypes(PyArray_Descr *type1, PyArray_Descr *type2)#

如果type1type2实际上代表此平台上的等效类型(每个类型的fortran成员被忽略),则返回NPY_TRUE。例如,在32位平台上,NPY_LONGNPY_INT是等效的。否则返回NPY_FALSE

npy_bool PyArray_EquivArrTypes(PyArrayObject *a1, PyArrayObject *a2)#

如果a1a2是具有此平台上等效类型的数组,则返回NPY_TRUE

npy_bool PyArray_EquivTypenums(int typenum1, int typenum2)#

PyArray_EquivTypes (…) 的特殊情况,它不接受灵活的数据类型,但可能更容易调用。

int PyArray_EquivByteorders(int b1, int b2)#

如果字节序字符b1b2NPY_LITTLENPY_BIGNPY_NATIVENPY_IGNORE)相等或在其对本机字节序的规范方面等效,则为真。因此,在小端机器上NPY_LITTLENPY_NATIVE是等效的,而它们在大端机器上则不等效。

数据类型转换#

PyObject *PyArray_Cast(PyArrayObject *arr, int typenum)#

主要用于与Numeric C-API 向后兼容,以及对非灵活类型的简单类型转换。返回一个新的数组对象,其元素为arr 中的元素转换为数据类型typenumtypenum必须是枚举类型之一,而不是灵活类型。

PyObject *PyArray_CastToType(PyArrayObject *arr, PyArray_Descr *type, int fortran)#

返回一个指定type 的新数组,并根据需要转换arr 的元素。fortran 参数指定输出数组的顺序。

int PyArray_CastTo(PyArrayObject *out, PyArrayObject *in)#

从1.6版本开始,此函数只是简单地调用PyArray_CopyInto,后者处理类型转换。

将数组in 的元素转换为数组out。输出数组应该是可写的,其元素个数是输入数组元素个数的整数倍(可以在out中放置多个副本),并且具有作为内置类型之一的数据类型。成功返回0,出错返回-1。

int PyArray_CanCastSafely(int fromtype, int totype)#

如果数据类型为fromtype 的数组可以安全地转换为数据类型为totype 的数组而不会丢失信息,则返回非零值。一个例外是允许将64位整数转换为64位浮点数,即使这可能会在大型整数上丢失精度,这样可以避免在没有明确请求的情况下大量使用长双精度浮点数。此函数不根据它们的长度检查灵活数组类型。

int PyArray_CanCastTo(PyArray_Descr *fromtype, PyArray_Descr *totype)#

在NumPy 1.6及更高版本中,PyArray_CanCastTypeTo 已取代此函数。

等效于PyArray_CanCastTypeTo(fromtype, totype, NPY_SAFE_CASTING)。

int PyArray_CanCastTypeTo(PyArray_Descr *fromtype, PyArray_Descr *totype, NPY_CASTING casting)#

根据转换规则casting,如果数据类型为fromtype(可以包含灵活类型)的数组可以安全地转换为数据类型为totype(可以包含灵活类型)的数组,则返回非零值。对于使用NPY_SAFE_CASTING 的简单类型,这基本上是PyArray_CanCastSafely 的一个包装器,但是对于诸如字符串或 Unicode 之类的灵活类型,它会生成考虑其大小的结果。只有当字符串或 Unicode 类型足够大到可以容纳要从中转换的整数/浮点类型的最大值时,整数和浮点类型才能使用NPY_SAFE_CASTING 转换为字符串或 Unicode 类型。

int PyArray_CanCastArrayTo(PyArrayObject *arr, PyArray_Descr *totype, NPY_CASTING casting)#

根据casting 中给出的转换规则,如果arr 可以转换为totype,则返回非零值。如果arr 是数组标量,则会考虑其值,并且当将值转换为较小的类型时不会溢出或截断为整数时,也会返回非零值。

PyArray_Descr *PyArray_MinScalarType(PyArrayObject *arr)#

注意

随着NumPy 2中NEP 50的采用,此函数不再用于内部。目前提供它是为了向后兼容,但预计最终会被弃用。

如果arr 是一个数组,则返回其数据类型描述符;但如果arr 是一个数组标量(具有0维),则查找最小大小的数据类型,可以将该值转换为该类型而不会溢出或截断为整数。

此函数不会将复数降级为浮点数,也不会将任何类型降级为布尔值,但当标量值为正时,会将有符号整数降级为无符号整数。

PyArray_Descr *PyArray_PromoteTypes(PyArray_Descr *type1, PyArray_Descr *type2)#

查找可以安全地转换type1type2 的最小大小和类型的数椐类型。此函数是对称的且满足结合律。字符串或 Unicode 结果将是存储输入类型转换为字符串或 Unicode 后的最大值的适当大小。

PyArray_Descr *PyArray_ResultType(npy_intp narrs, PyArrayObject **arrs, npy_intp ndtypes, PyArray_Descr **dtypes)#

这将类型提升应用于所有输入数组和dtype对象,使用NumPy组合标量和数组的规则来确定对具有给定操作数集的操作的输出类型。这与ufunc生成的相同结果类型。

有关类型提升算法的更多详细信息,请参阅numpy.result_type 的文档。

int PyArray_ObjectType(PyObject *op, int mintype)#

此函数已被PyArray_ResultType 取代。

此函数对于确定两个或多个数组可以转换到的通用类型很有用。它仅适用于非灵活数组类型,因为没有传递项目大小信息。mintype 参数表示可接受的最小类型,op 表示将转换为数组的对象。返回值是表示op 应具有的数据类型的枚举类型编号。

PyArrayObject **PyArray_ConvertToCommonType(PyObject *op, int *n)#

此功能在很大程度上已被1.6版中引入的迭代器NpyIter(使用标志NPY_ITER_COMMON_DTYPE或对所有操作数使用相同dtype参数)所取代。

将包含在op中的Python对象序列转换为每个具有相同数据类型的ndarray数组。类型的选择方式与PyArray_ResultType相同。序列的长度返回到n中,一个长度为nPyArrayObject指针数组是返回值(如果发生错误,则为NULL)。返回的数组必须由此例程的调用者释放(使用PyDataMem_FREE),并且其中的所有数组对象都必须进行DECREF操作,否则会发生内存泄漏。下面的示例模板代码展示了典型的用法。

mps = PyArray_ConvertToCommonType(obj, &n);
if (mps==NULL) return NULL;
{code}
<before return>
for (i=0; i<n; i++) Py_DECREF(mps[i]);
PyDataMem_FREE(mps);
{return}
char *PyArray_Zero(PyArrayObject *arr)#

指向新创建的内存的指针,大小为arr ->itemsize,其中包含该类型的0的表示。返回的指针ret**必须**使用PyDataMem_FREE (ret) 在不再需要时释放。

char *PyArray_One(PyArrayObject *arr)#

指向新创建的内存的指针,大小为arr ->itemsize,其中包含该类型的1的表示。返回的指针ret**必须**使用PyDataMem_FREE (ret) 在不再需要时释放。

int PyArray_ValidType(int typenum)#

如果typenum表示有效的类型编号(内置的、用户定义的或字符代码),则返回NPY_TRUE。否则,此函数返回NPY_FALSE

用户自定义数据类型#

void PyArray_InitArrFuncs(PyArray_ArrFuncs *f)#

将所有函数指针和成员初始化为NULL

int PyArray_RegisterDataType(PyArray_DescrProto *dtype)#

注意

从NumPy 2.0开始,此API被认为是旧版API,新的DType API功能更强大,并提供了额外的灵活性。该API最终可能会被弃用,但目前仍在继续支持。

针对NumPy 1.x和2.x编译

NumPy 2.x需要传入一个PyArray_DescrProto类型的结构体,而不是PyArray_Descr。这是为了允许更改。为了使代码能够在1.x和2.x上运行和编译,您需要将结构体的类型更改为PyArray_DescrProto并添加

/* Allow compiling on NumPy 1.x */
#if NPY_ABI_VERSION < 0x02000000
#define PyArray_DescrProto PyArray_Descr
#endif

用于1.x兼容性。此外,该结构体将不再是实际的描述符,只有其类型编号将被更新。成功注册后,您必须使用以下方法获取实际的dtype:

int type_num = PyArray_RegisterDataType(&my_descr_proto);
if (type_num < 0) {
    /* error */
}
PyArray_Descr *my_descr = PyArray_DescrFromType(type_num);

通过这两个更改,代码应该能够在1.x和2.x或更高版本上编译和运行。

如果您不太可能堆分配dtype结构体,则应该在NumPy 2中再次释放它,因为会创建一个副本。该结构体不是有效的Python对象,因此不要在其上使用Py_DECREF

将数据类型注册为数组的新用户定义数据类型。该类型的大多数条目都必须填写完整。这并不总是被检查,错误可能会导致段错误。特别是,dtype结构体的typeobj成员必须填充一个Python类型,该类型具有与dtype的elsize成员对应的固定大小的元素大小。此外,f成员必须具有必需的函数:nonzero、copyswap、copyswapn、getitem、setitem和cast(如果不需要支持,则一些cast函数可以为NULL)。为避免混淆,您应该选择一个唯一的字符类型代码,但这并非强制执行,并且内部也不依赖于此。

返回一个用户定义的类型编号,该编号唯一标识该类型。然后可以使用返回的类型编号从PyArray_DescrFromType获取指向新结构体的指针。如果发生错误,则返回-1。如果此dtype已被注册(仅通过指针的地址检查),则返回先前分配的类型编号。

NumPy已知用户DType的数量存储在NPY_NUMUSERTYPES中,这是一个在C API中公开的静态全局变量。访问此符号本身**不是**线程安全的。如果您出于某种原因需要在多线程上下文中使用此API,则需要添加您自己的锁,NumPy不保证可以以线程安全的方式添加新的数据类型。

int PyArray_RegisterCastFunc(PyArray_Descr *descr, int totype, PyArray_VectorUnaryFunc *castfunc)#

注册一个低级转换函数castfunc,用于从数据类型descr转换为给定的数据类型编号totype。任何旧的转换函数都会被覆盖。成功时返回0,失败时返回-1

type PyArray_VectorUnaryFunc#

低级转换函数的函数指针类型。

int PyArray_RegisterCanCast(PyArray_Descr *descr, int totype, NPY_SCALARKIND scalar)#

将数据类型编号totype注册为可以从给定scalar类型的descr数据类型对象转换而来。使用scalar = NPY_NOSCALAR 来注册数据类型为descr的数组可以安全地转换为类型编号为totype的数据类型。成功时返回0,失败时返回-1。

NPY_OBJECT的特殊函数#

警告

在使用填充对象的数组或缓冲区时,NumPy尝试确保在读取任何数据之前,此类缓冲区已填充None。但是,可能存在仅将数组初始化为NULL的代码路径。NumPy本身接受NULL作为None的别名,但在调试模式下编译时可能会assertNULL

由于NumPy在使用None进行初始化方面尚不一致,用户**必须**预期在使用NumPy创建的缓冲区时会得到NULL值。用户还**应该**确保向NumPy传递完全初始化的缓冲区,因为NumPy将来可能会对此提出严格的要求。

目前,我们的目标是确保NumPy在读取对象数组之前始终对其进行初始化。任何未能做到这一点的情况都将被视为错误。将来,用户在从任何数组读取时都可以依赖非NULL值,尽管写入新创建的数组的异常可能仍然存在(例如,ufunc代码中的输出数组)。截至NumPy 1.23,已知存在未正确填充的代码路径。

int PyArray_INCREF(PyArrayObject *op)#

用于包含任何Python对象的数组op。它根据op的数据类型递增数组中每个对象的引用计数。如果发生错误,则返回-1,否则返回0。

void PyArray_Item_INCREF(char *ptr, PyArray_Descr *dtype)#

一个函数,根据数据类型dtype递增位置ptr处所有对象的引用计数。如果ptr是结构化类型的开头,并且在任何偏移量处都有一个对象,则此函数将(递归地)递增结构化类型中所有类似对象项的引用计数。

int PyArray_XDECREF(PyArrayObject *op)#

用于包含任何Python对象的数组op。它根据op的数据类型递减数组中每个对象的引用计数。正常的返回值是0。如果发生错误,则返回-1。

void PyArray_Item_XDECREF(char *ptr, PyArray_Descr *dtype)#

一个函数,递减位置ptr处所有类似对象项的引用计数,如数据类型dtype中记录的那样。此函数递归工作,因此,如果dtype本身包含具有包含类似对象项的数据类型字段,则所有类似对象的字段都将被XDDECREF 'd

int PyArray_SetWritebackIfCopyBase(PyArrayObject *arr, PyArrayObject *base)#

前提条件:arrbase的副本(尽管步幅、顺序等可能不同)。设置NPY_ARRAY_WRITEBACKIFCOPY标志和arr->base,并将base设置为READONLY。在调用Py_DECREF之前,调用PyArray_ResolveWritebackIfCopy,以便将任何更改复制回base并重置READONLY标志。

成功返回0,失败返回-1。

数组标志#

PyArrayObject结构的flags属性包含有关数组使用的内存(由data成员指向)的重要信息。必须保持此标志信息的准确性,否则可能会导致奇怪的结果甚至段错误。

有6个(二进制)标志描述数据缓冲区使用的内存区域。这些常量在arrayobject.h中定义,并确定标志的位位置。Python 还提供了一个很好的基于属性的接口和一个类似字典的接口,用于获取(如果合适,则设置)这些标志。

ndarray可以指向各种类型的内存区域,因此需要这些标志。如果您在C代码中获得了一个任意的PyArrayObject,则需要了解已设置的标志。如果您需要保证某种类型的数组(例如NPY_ARRAY_C_CONTIGUOUSNPY_ARRAY_BEHAVED),则将这些要求传递到PyArray_FromAny函数中。

在1.6版及更早版本的NumPy中,以下标志没有_ARRAY_宏命名空间。这种形式的常量名称在1.7版中已弃用。

基本数组标志#

ndarray可以拥有一个数据段,它不是一个简单的、行为良好的连续内存块,您可以对其进行操作。它可能未与字边界对齐(在某些平台上非常重要)。它的数据可能与机器识别的字节顺序不同。它可能不可写。它可能采用Fortran连续顺序。数组标志用于指示有关与数组关联的数据可以说明什么。

NPY_ARRAY_C_CONTIGUOUS#

数据区域采用C风格的连续顺序(最后一个索引变化最快)。

NPY_ARRAY_F_CONTIGUOUS#

数据区域采用Fortran风格的连续顺序(第一个索引变化最快)。

注意

数组可以同时是C风格和Fortran风格的连续的。对于一维数组,这是很清楚的,但对于更高维的数组也可能是正确的。

即使对于连续数组,如果arr.shape[dim] == 1或数组没有元素,则给定维度arr.strides[dim]的步幅可能是任意的。对于C风格的连续数组,self.strides[-1] == self.itemsize通常并不成立;对于Fortran风格的连续数组,self.strides[0] == self.itemsize通常也不成立。从C API访问数组itemsize的正确方法是PyArray_ITEMSIZE(arr)

NPY_ARRAY_OWNDATA#

数据区域由该数组拥有。切勿手动设置,而应创建一个包装数据的PyObject并将数组的base设置为该对象。例如,请参见test_mem_policy中的测试。

NPY_ARRAY_ALIGNED#

数据区域和所有数组元素都已正确对齐。

NPY_ARRAY_WRITEABLE#

数据区域可以写入。

请注意,以上3个标志的定义方式是:一个新的、行为良好的数组将这些标志定义为true。

NPY_ARRAY_WRITEBACKIFCOPY#

数据区域表示一个(行为良好的)副本,当调用PyArray_ResolveWritebackIfCopy时,应将其信息传输回原始数据。

这是一个特殊标志,如果该数组表示由于用户在PyArray_FromAny中需要某些标志而创建的副本(并且必须对其他一些数组进行复制,并且用户要求在这种情况下设置此标志),则会设置此标志。然后,base属性指向“行为不良”的数组(设置为read_only)。PyArray_ResolveWritebackIfCopy会将其内容复制回“行为不良”的数组(如果需要则进行转换),并将“行为不良”的数组重置为NPY_ARRAY_WRITEABLE。如果“行为不良”的数组最初不是NPY_ARRAY_WRITEABLE,则PyArray_FromAny将返回错误,因为NPY_ARRAY_WRITEBACKIFCOPY将无法实现。

PyArray_UpdateFlags (obj, flags) 将更新 obj->flags,其中 flags 可以是 NPY_ARRAY_C_CONTIGUOUSNPY_ARRAY_F_CONTIGUOUSNPY_ARRAY_ALIGNEDNPY_ARRAY_WRITEABLE 中的任意一个。

数组标志的组合#

NPY_ARRAY_BEHAVED#

NPY_ARRAY_ALIGNED | NPY_ARRAY_WRITEABLE

NPY_ARRAY_CARRAY#

NPY_ARRAY_C_CONTIGUOUS | NPY_ARRAY_BEHAVED

NPY_ARRAY_CARRAY_RO#

NPY_ARRAY_C_CONTIGUOUS | NPY_ARRAY_ALIGNED

NPY_ARRAY_FARRAY#

NPY_ARRAY_F_CONTIGUOUS | NPY_ARRAY_BEHAVED

NPY_ARRAY_FARRAY_RO#

NPY_ARRAY_F_CONTIGUOUS | NPY_ARRAY_ALIGNED

NPY_ARRAY_DEFAULT#

NPY_ARRAY_CARRAY

NPY_ARRAY_IN_ARRAY#

NPY_ARRAY_C_CONTIGUOUS | NPY_ARRAY_ALIGNED

NPY_ARRAY_IN_FARRAY#

NPY_ARRAY_F_CONTIGUOUS | NPY_ARRAY_ALIGNED

NPY_ARRAY_OUT_ARRAY#

NPY_ARRAY_C_CONTIGUOUS | NPY_ARRAY_WRITEABLE | NPY_ARRAY_ALIGNED

NPY_ARRAY_OUT_FARRAY#

NPY_ARRAY_F_CONTIGUOUS | NPY_ARRAY_WRITEABLE | NPY_ARRAY_ALIGNED

NPY_ARRAY_INOUT_ARRAY#

NPY_ARRAY_C_CONTIGUOUS | NPY_ARRAY_WRITEABLE | NPY_ARRAY_ALIGNED | NPY_ARRAY_WRITEBACKIFCOPY

NPY_ARRAY_INOUT_FARRAY#

NPY_ARRAY_F_CONTIGUOUS | NPY_ARRAY_WRITEABLE | NPY_ARRAY_ALIGNED | NPY_ARRAY_WRITEBACKIFCOPY

NPY_ARRAY_UPDATE_ALL#

NPY_ARRAY_C_CONTIGUOUS | NPY_ARRAY_F_CONTIGUOUS | NPY_ARRAY_ALIGNED

类似标志的常量#

这些常量用于 PyArray_FromAny(及其宏形式)中,以指定新数组的所需属性。

NPY_ARRAY_FORCECAST#

强制转换为所需类型,即使这可能会导致信息丢失。

NPY_ARRAY_ENSURECOPY#

确保生成的数组是原始数组的副本。

NPY_ARRAY_ENSUREARRAY#

确保生成的對象是一個實際的 ndarray,而不是其子類。

这些常量用于 PyArray_CheckFromAny(及其宏形式)中,以指定新数组的所需属性。

NPY_ARRAY_NOTSWAPPED#

确保返回的数组具有机器字节序的数据类型描述符,覆盖 _dtype_ 参数中的任何规范。通常,字节序要求由 _dtype_ 参数确定。如果设置了此标志,并且 dtype 参数未指示机器字节序描述符(或为 NULL,并且对象已经是具有非机器字节序数据类型描述符的数组),则创建一个新的数据类型描述符并将其字节序字段设置为本地字节序。

NPY_ARRAY_BEHAVED_NS#

NPY_ARRAY_ALIGNED | NPY_ARRAY_WRITEABLE | NPY_ARRAY_NOTSWAPPED

NPY_ARRAY_ELEMENTSTRIDES#

确保返回的数组的步长是元素大小的倍数。

标志检查#

对于所有这些宏,_arr_ 必须是 PyArray_Type(或其子类)的实例。

int PyArray_CHKFLAGS(PyObject *arr, int flags)#

第一个参数 arr 必须是 ndarray 或其子类。参数 _flags_ 应为一个整数,该整数由数组可能具有的标志的按位组合构成:NPY_ARRAY_C_CONTIGUOUSNPY_ARRAY_F_CONTIGUOUSNPY_ARRAY_OWNDATANPY_ARRAY_ALIGNEDNPY_ARRAY_WRITEABLENPY_ARRAY_WRITEBACKIFCOPY

int PyArray_IS_C_CONTIGUOUS(PyObject *arr)#

如果 _arr_ 是 C 样式连续的,则评估为真。

int PyArray_IS_F_CONTIGUOUS(PyObject *arr)#

判断arr是否为Fortran风格连续存储。

int PyArray_ISFORTRAN(PyObject *arr)#

如果arr是Fortran风格连续存储且不是C风格连续存储,则返回真。 PyArray_IS_F_CONTIGUOUS 是检测Fortran风格连续存储的正确方法。

int PyArray_ISWRITEABLE(PyObject *arr)#

如果arr的数据区域可写,则返回真。

int PyArray_ISALIGNED(PyObject *arr)#

如果arr的数据区域在机器上正确对齐,则返回真。

int PyArray_ISBEHAVED(PyObject *arr)#

如果arr的数据区域已对齐、可写且根据其描述符采用机器字节序,则返回真。

int PyArray_ISBEHAVED_RO(PyObject *arr)#

如果arr的数据区域已对齐且采用机器字节序,则返回真。

int PyArray_ISCARRAY(PyObject *arr)#

如果arr的数据区域为C风格连续存储,并且PyArray_ISBEHAVED (arr) 为真,则返回真。

int PyArray_ISFARRAY(PyObject *arr)#

如果arr的数据区域为Fortran风格连续存储,并且PyArray_ISBEHAVED (arr) 为真,则返回真。

int PyArray_ISCARRAY_RO(PyObject *arr)#

如果arr的数据区域为C风格连续存储,已对齐且采用机器字节序,则返回真。

int PyArray_ISFARRAY_RO(PyObject *arr)#

如果arr的数据区域为Fortran风格连续存储,已对齐且采用机器字节序,则返回真。

int PyArray_ISONESEGMENT(PyObject *arr)#

如果arr的数据区域由单个(C风格或Fortran风格)连续段组成,则返回真。

void PyArray_UpdateFlags(PyArrayObject *arr, int flagmask)#

NPY_ARRAY_C_CONTIGUOUSNPY_ARRAY_ALIGNEDNPY_ARRAY_F_CONTIGUOUS 数组标志可以从数组对象本身“计算”出来。此例程通过执行必要的计算来更新arr中由flagmask指定的这些标志中的一个或多个。

警告

每当执行可能导致这些标志改变的数组操作时,务必保持标志更新(使用PyArray_UpdateFlags 可以有所帮助)。NumPy中依赖于这些标志状态的后续计算不会重复计算来更新它们。

int PyArray_FailUnlessWriteable(PyArrayObject *obj, const char *name)#

如果obj可写,则此函数不执行任何操作并返回0。如果obj不可写,则引发异常并返回-1。它还可以执行其他内部操作,例如对正在转换为视图的数组发出警告。在写入数组之前,务必在某个时刻调用此函数。

name是数组的名称,用于提供更好的错误消息。它可以是诸如“赋值目标”、“输出数组”或仅仅是“数组”之类的内容。

数组方法API#

数组方法循环旨在作为一种通用的机制,用于编写数组循环,包括ufunc循环和类型转换。公共API在numpy/dtype_api.h头文件中定义。有关数组方法API中公开的C结构的文档,请参见PyArrayMethod_Context和PyArrayMethod_Spec

槽和类型定义#

这些用于标识数组方法槽实现哪种类型的函数。有关必须为每个槽实现的函数的文档,请参见下面的槽和类型定义

NPY_METH_resolve_descriptors#
typedef NPY_CASTING (PyArrayMethod_ResolveDescriptors)(struct PyArrayMethodObject_tag *method, PyArray_DTypeMeta *const *dtypes, PyArray_Descr *const *given_descrs, PyArray_Descr **loop_descrs, npy_intp *view_offset)#

此函数用于根据操作数的描述符设置操作的描述符。例如,一个具有两个输入操作数和一个输出操作数的 ufunc 操作,在 Python API 中调用时未设置 out,则 resolve_descriptors 将接收两个操作数的描述符,并根据 ArrayMethod 设置的输出 DType 确定要用于输出的正确描述符。如果设置了 out,则输出描述符也将传入,并且不应被覆盖。

method 是指向底层转换或 ufunc 循环的指针。将来我们可能会公开此结构,但目前这是一个不透明指针,无法检查该方法。dtypes 是一个长度为 nargsPyArray_DTypeMeta 指针数组,given_descrs 是一个长度为 nargs 的输入描述符实例数组(如果用户未提供输出,则输出描述符可以为 NULL),而 loop_descrs 是一个长度为 nargs 的描述符数组,必须由 resolve descriptors 实现填充。view_offset 目前仅对转换有用,通常可以忽略。当转换不需要任何操作时,可以通过将 view_offset 设置为 0 来表示。发生错误时,必须返回 (NPY_CASTING)-1 并设置错误。

NPY_METH_strided_loop#
NPY_METH_contiguous_loop#
NPY_METH_unaligned_strided_loop#
NPY_METH_unaligned_contiguous_loop#

实现行为(ufunc 或转换)的一维步进循环。在大多数情况下,NPY_METH_strided_loop 是通用的且唯一需要实现的版本。NPY_METH_contiguous_loop 可以额外实现为更轻量级/更快的版本,当所有输入和输出都是连续的时使用。

为了处理可能未对齐的数据,NumPy 需要能够将未对齐的数据复制到对齐的数据。实现新的 DType 时,其“转换”或复制需要实现 NPY_METH_unaligned_strided_loop。与普通版本不同,此循环不能假设可以以对齐的方式访问数据。这些循环必须在访问或存储之前复制每个值。

type_in in_value;
type_out out_value
memcpy(&value, in_data, sizeof(type_in));
out_value = in_value;
memcpy(out_data, &out_value, sizeof(type_out)

而普通循环可以直接使用

*(type_out *)out_data = *(type_in)in_data;

未对齐循环目前仅用于转换,并且永远不会在 ufunc 中被选择(ufunc 创建临时副本以确保对齐输入)。当定义 NPY_METH_get_loop 时,这些插槽 ID 将被忽略,而使用 get_loop 函数返回的任何循环。

NPY_METH_contiguous_indexed_loop#

一种专门的内部循环选项,用于加速常见的 ufunc.at 计算。

typedef int (PyArrayMethod_StridedLoop)(PyArrayMethod_Context *context, char *const *data, const npy_intp *dimensions, const npy_intp *strides, NpyAuxData *auxdata)#

ArrayMethod 循环的实现。上面列出的所有循环槽 ID 都必须提供 PyArrayMethod_StridedLoop 实现。context 是一个包含循环操作上下文的结构——特别是输入描述符。data 是指向输入和输出数组缓冲区开头的指针数组。dimensions 是操作的循环维度。strides 是一个长度为 nargs 的每个输入步长的数组。auxdata 是一组可选的辅助数据,可以传入循环中——这有助于打开和关闭可选行为,或者通过允许类似的 ufunc 共享循环实现或分配在多个步进循环调用中持续存在的空间来减少样板代码。

NPY_METH_get_loop#

允许对循环选择进行更细粒度的控制。接受 PyArrayMethod_GetLoop 的实现,该实现依次返回步进循环实现。如果定义了 NPY_METH_get_loop,则将忽略其他循环槽 ID(如果指定)。

typedef int (PyArrayMethod_GetLoop)(PyArrayMethod_Context *context, int aligned, int move_references, const npy_intp *strides, PyArrayMethod_StridedLoop **out_loop, NpyAuxData **out_transferdata, NPY_ARRAYMETHOD_FLAGS *flags);#

在运行时设置要用于操作的循环。context 是操作的运行时上下文。aligned 指示循环的数据访问是对齐的 (1) 还是未对齐的 (0)。move_references 指示是否应复制数据中的嵌入式引用。strides 是输入数组的步长,out_loop 是一个必须用指向循环实现的指针填充的指针。out_transferdata 可选地填充以允许将额外用户定义的上下文传递到操作。flags 必须用与操作相关的 ArrayMethod 标志填充。例如,这对于指示内部循环是否需要持有 Python GIL 是必要的。

NPY_METH_get_reduction_initial#
typedef int (PyArrayMethod_GetReductionInitial)(PyArrayMethod_Context *context, npy_bool reduction_is_empty, char *initial)#

查询 ArrayMethod 以获取用于约简的初始值。context 是 ArrayMethod 上下文,主要用于访问输入描述符。reduction_is_empty 指示约简是否为空。当它为空时,返回的值可能不同。在这种情况下,它是一个“默认”值,可能与通常使用的“标识”值不同。例如

  • sum([]) 的默认值为0.0。但其他情况下,正确的恒等元是-0.0,因为它保留了sum([-0.0]) 的符号。

  • 对于对象,我们不使用恒等元,但对于空的sum([], dtype=object)prod([], dtype=object),返回默认值01。这使得np.sum(np.array(["a", "b"], dtype=object)) 可以正常工作。

  • 对于max-infINT_MIN 是恒等元,但至少INT_MIN 在没有元素时不是一个好的默认值

initial 是指向初始值数据的指针,应该将其填充。返回 -1、0 或 1,分别表示错误、没有初始值和初始值已成功填充。如果没有初始值是正确的,则不能给出错误,因为 NumPy 即使在严格不需要这样做的情况下也可能会调用它。

标志#

枚举 NPY_ARRAYMETHOD_FLAGS#

这些标志允许切换 ArrayMethod 循环的自定义运行时行为。例如,如果 ufunc 根本不可能触发浮点错误,则在注册 ufunc 时应设置该 ufunc 上的NPY_METH_NO_FLOATINGPOINT_ERRORS 标志。

枚举器 NPY_METH_REQUIRES_PYAPI#

指示方法必须持有 GIL。如果未设置此标志,则在调用循环之前释放 GIL。

枚举器 NPY_METH_NO_FLOATINGPOINT_ERRORS#

指示方法不会生成浮点错误,因此可以跳过循环完成后检查浮点错误。

枚举器 NPY_METH_SUPPORTS_UNALIGNED#

指示方法支持未对齐访问。

枚举器 NPY_METH_IS_REORDERABLE#

指示重复应用循环的结果(例如,在归约运算中)不依赖于应用顺序。

枚举器 NPY_METH_RUNTIME_FLAGS#

可以在运行时更改的标志。

类型定义#

下面描述了 ArrayMethod API 用户可以实现的函数的类型定义。

typedef int (PyArrayMethod_TraverseLoop)(void *traverse_context, const PyArray_Descr *descr, char *data, npy_intp size, npy_intp stride, NpyAuxData *auxdata)#

在单个数组上工作的遍历循环。这类似于一般的步幅循环函数。这专为需要访问单个数组的每个元素的循环而设计。

目前,这用于通过NPY_DT_get_clear_loop DType API 钩子进行数组清除,以及通过NPY_DT_get_fill_zero_loop DType API 钩子进行零填充。这些对于处理存储对 python 对象或堆分配数据的嵌入式引用的数组最为有用。

descr 是数组的描述符,data 是指向数组缓冲区的指针,size 是数组缓冲区的 1D 大小,stride 是步幅,auxdata 是循环的可选额外数据。

传入traverse_context 是因为我们将来可能需要传入解释器状态或类似内容,但我们不想传入完整的上下文(带有指向 dtype、方法、调用者的指针,所有这些对于遍历函数都没有意义)。我们目前假设此上下文将来可以仅被传递(对于结构化 dtype)。

typedef int (PyArrayMethod_GetTraverseLoop)(void *traverse_context, const PyArray_Descr *descr, int aligned, npy_intp fixed_stride, PyArrayMethod_TraverseLoop **out_loop, NpyAuxData **out_auxdata, NPY_ARRAYMETHOD_FLAGS *flags)#

特定于 dtype 遍历的简化 get_loop 函数

它应该设置遍历循环所需的标志并将out_loop 设置为循环函数,该函数必须是有效的PyArrayMethod_TraverseLoop 指针。目前,这用于填充存储嵌入式引用的数组和清除这些数组。

API 函数和类型定义#

这些函数是 NumPy 数组 API 的主要部分,并与 ArrayMethod API 的其余部分一起添加。

int PyUFunc_AddLoopFromSpec(PyObject *ufunc, PyArrayMethod_Spec *spec)#

直接从给定的 ArrayMethod 规范向 ufunc 添加循环。主要的 ufunc 注册函数。这向 ufunc 添加了一个新的实现/循环。它替换了PyUFunc_RegisterLoopForType

int PyUFunc_AddPromoter(PyObject *ufunc, PyObject *DType_tuple, PyObject *promoter)#

注意,目前除非输出dtype也是签名的一部分,否则输出dtype始终为NULL。这是一个实现细节,将来可能会更改。但是,通常情况下,提升器不需要输出dtype。为ufunc注册一个新的提升器。第一个参数是要注册提升器的ufunc。第二个参数是一个Python元组,包含与ufunc的输入和输出数量匹配的DType或None。最后一个参数是一个提升器,它是一个存储在PyCapsule中的函数。它传递操作和请求的DType签名,并可以对其进行修改以尝试新的搜索以匹配循环/提升器。

typedef int (PyArrayMethod_PromoterFunction)(PyObject *ufunc, PyArray_DTypeMeta *const op_dtypes[], PyArray_DTypeMeta *const signature[], PyArray_DTypeMeta *new_op_dtypes[])#

提升器函数的类型,必须将其包装到名为PyCapsule且名称为"numpy._ufunc_promoter"的PyCapsule中。它传递操作和请求的DType签名,并可以更改签名以尝试搜索新的循环或提升器,通过将输入转换为“提升的”DType来完成操作。

int PyUFunc_GiveFloatingpointErrors(const char *name, int fpe_errors)#

以考虑通过numpy.errstate配置的错误信号的方式,执行浮点运算后检查浮点错误。获取操作名称以用于错误消息,以及一个整数标志,该标志是NPY_FPE_DIVIDEBYZERONPY_FPE_OVERFLOWNPY_FPE_UNDERFLOWNPY_FPE_INVALID之一,以指示要检查的错误。

失败时返回-1(引发错误),成功时返回0。

int PyUFunc_AddWrappingLoop(PyObject *ufunc_obj, PyArray_DTypeMeta *new_dtypes[], PyArray_DTypeMeta *wrapped_dtypes[], PyArrayMethod_TranslateGivenDescriptors *translate_given_descrs, PyArrayMethod_TranslateLoopDescriptors *translate_loop_descrs)#

允许在现有的ufunc循环周围创建一个相当轻量级的包装器。其主要思想是用于单元,因为目前这略微受限,因为它强制你不能使用来自另一个ufunc的循环。

typedef int (PyArrayMethod_TranslateGivenDescriptors)(int nin, int nout, PyArray_DTypeMeta *wrapped_dtypes[], PyArray_Descr *given_descrs[], PyArray_Descr *new_descrs[]);#

将给定的描述符(传递到resolve_descriptors)转换并为包装的循环转换它们。新的描述符必须能够用旧的描述符查看,必须支持NULL(对于输出参数),并且通常应该转发。

此函数的输出将用于构造参数的视图,就好像它们是转换后的dtype一样,并且不使用转换。这意味着此机制主要对“包装”另一个DType实现的DType有用。例如,单元DType可以使用它来包装现有的浮点DType,而无需重新实现低级ufunc逻辑。在单元示例中,resolve_descriptors将处理根据输入单元计算输出单元。

typedef int (PyArrayMethod_TranslateLoopDescriptors)(int nin, int nout, PyArray_DTypeMeta *new_dtypes[], PyArray_Descr *given_descrs[], PyArray_Descr *original_descrs[], PyArray_Descr *loop_descrs[]);#

将实际循环描述符(由原始resolve_descriptors函数返回)转换为输出数组应使用的描述符的函数。此函数必须返回“可查看”的类型,它不能以任何会破坏内部循环逻辑的形式对其进行更改。不需要支持NULL。

包装循环示例#

假设你想要为WrappedDoubleDType包装float64乘法实现。你可以这样添加一个包装循环

PyArray_DTypeMeta *orig_dtypes[3] = {
    &WrappedDoubleDType, &WrappedDoubleDType, &WrappedDoubleDType};
PyArray_DTypeMeta *wrapped_dtypes[3] = {
     &PyArray_Float64DType, &PyArray_Float64DType, &PyArray_Float64DType}

PyObject *mod = PyImport_ImportModule("numpy");
if (mod == NULL) {
    return -1;
}
PyObject *multiply = PyObject_GetAttrString(mod, "multiply");
Py_DECREF(mod);

if (multiply == NULL) {
    return -1;
}

int res = PyUFunc_AddWrappingLoop(
    multiply, orig_dtypes, wrapped_dtypes, &translate_given_descrs
    &translate_loop_descrs);

Py_DECREF(multiply);

注意,这也需要在此代码之上定义两个函数

static int
translate_given_descrs(int nin, int nout,
                       PyArray_DTypeMeta *NPY_UNUSED(wrapped_dtypes[]),
                       PyArray_Descr *given_descrs[],
                       PyArray_Descr *new_descrs[])
{
    for (int i = 0; i < nin + nout; i++) {
        if (given_descrs[i] == NULL) {
            new_descrs[i] = NULL;
        }
        else {
            new_descrs[i] = PyArray_DescrFromType(NPY_DOUBLE);
        }
    }
    return 0;
}

static int
translate_loop_descrs(int nin, int NPY_UNUSED(nout),
                      PyArray_DTypeMeta *NPY_UNUSED(new_dtypes[]),
                      PyArray_Descr *given_descrs[],
                      PyArray_Descr *original_descrs[],
                      PyArray_Descr *loop_descrs[])
{
    // more complicated parametric DTypes may need to
    // to do additional checking, but we know the wrapped
    // DTypes *have* to be float64 for this example.
    loop_descrs[0] = PyArray_DescrFromType(NPY_FLOAT64);
    Py_INCREF(loop_descrs[0]);
    loop_descrs[1] = PyArray_DescrFromType(NPY_FLOAT64);
    Py_INCREF(loop_descrs[1]);
    loop_descrs[2] = PyArray_DescrFromType(NPY_FLOAT64);
    Py_INCREF(loop_descrs[2]);
}

调用数组方法的API#

转换#

PyObject * PyArray_GetField(PyArrayObject *self, PyArray_Descr *dtype, int offset)

等效于 ndarray.getfield (self, dtype, offset)。此函数 窃取对 PyArray_Descr 的引用,并返回一个使用当前数组中指定字节偏移量 offset 的数据的新数组,其数据类型为给定的 dtypeoffset 加上新数组类型的元素大小必须小于 self->descr->elsize,否则将引发错误。使用与原始数组相同的形状和步幅。因此,此函数的作用是从结构化数组中返回一个字段。但是,它也可以用于从任何数组类型中选择特定的字节或字节组。

int PyArray_SetField(PyArrayObject *self, PyArray_Descr *dtype, int offset, PyObject *val)

等效于 ndarray.setfield (self, val, dtype, offset)。将从字节偏移量 offset 开始,指定为 dtype 的字段设置为 valoffset 加上 dtype ->elsize 必须小于 self ->descr->elsize,否则将引发错误。否则,将 val 参数转换为数组并将其复制到指向的字段中。如有必要,将重复 val 的元素以填充目标数组,但是目标中的元素数量必须是 val 中元素数量的整数倍。

PyObject * PyArray_Byteswap(PyArrayObject *self, npy_bool inplace)

等效于 ndarray.byteswap (self, inplace)。返回一个其数据区域已进行字节交换的数组。如果 inplace 为非零值,则原地进行字节交换并返回对自身的引用。否则,创建一个字节交换的副本,并保持自身不变。

PyObject * PyArray_NewCopy(PyArrayObject *old, NPY_ORDER order)

等效于 ndarray.copy (self, fortran)。复制 old 数组。返回的数组始终已对齐且可写,其数据解释方式与旧数组相同。如果 orderNPY_CORDER,则返回 C 样式的连续数组。如果 orderNPY_FORTRANORDER,则返回 Fortran 样式的连续数组。如果 orderNPY_ANYORDER,则只有当旧数组为 Fortran 样式连续时,返回的数组才为 Fortran 样式连续;否则,它为 C 样式连续。

PyObject * PyArray_ToList(PyArrayObject *self)

等效于 ndarray.tolist (self)。从 self 返回嵌套的 Python 列表。

PyObject * PyArray_ToString(PyArrayObject *self, NPY_ORDER order)

等效于 ndarray.tobytes (self, order)。以 Python 字符串的形式返回此数组的字节。

PyObject * PyArray_ToFile(PyArrayObject *self, FILE *fp, char *sep, char *format)

以 C 样式连续的方式将 self 的内容写入文件指针 fp。如果 sep 字符串为 "" 或 NULL,则将数据写入为二进制字节。否则,使用 sep 字符串作为项目分隔符将 self 的内容写入文本。每个项目都将打印到文件中。如果 format 字符串不是 NULL 或 "",则它是一个 Python 打印语句格式字符串,显示如何写入项目。

int PyArray_Dump(PyObject *self, PyObject *file, int protocol)

self 中的对象序列化到给定的 file(字符串或 Python 文件对象)。如果 file 是 Python 字符串,则将其视为文件的名称,然后以二进制模式打开。使用给定的 protocol(如果 protocol 为负数,则使用最高可用的协议)。这是一个围绕 cPickle.dump(self, file, protocol) 的简单包装器。

PyObject * PyArray_Dumps(PyObject *self, int protocol)

self 中的对象序列化为 Python 字符串并返回它。使用提供的 Pickle protocol(如果 protocol 为负数,则使用最高可用的协议)。

int PyArray_FillWithScalar(PyArrayObject *arr, PyObject *obj)#

用给定的标量对象obj填充数组arr。该对象首先被转换为arr的数据类型,然后复制到每个位置。如果发生错误,则返回-1,否则返回0。

PyObject *PyArray_View(PyArrayObject *self, PyArray_Descr *dtype, PyTypeObject *ptype)#

等效于 ndarray.view (self, dtype)。返回数组self的新视图,可能具有不同的数据类型dtype和不同的数组子类ptype

如果dtypeNULL,则返回的数组将与self具有相同的数据类型。新的数据类型必须与self的大小一致。项大小必须相同,或者self必须是单段的,并且总字节数必须相同。在后一种情况下,返回数组的维度将在最后(或对于 Fortran 样式的连续数组而言为第一)维度上发生改变。返回数组和self的数据区域完全相同。

形状操作#

PyObject *PyArray_Newshape(PyArrayObject *self, PyArray_Dims *newshape, NPY_ORDER order)#

结果将是一个新数组(如果可能,指向与self相同的内存位置),但具有由newshape给定的形状。如果新形状与self的步幅不兼容,则将返回具有新指定形状的数组的副本。

PyObject *PyArray_Reshape(PyArrayObject *self, PyObject *shape)#

等效于 ndarray.reshape (self, shape),其中shape是一个序列。将shape转换为PyArray_Dims结构,并在内部调用PyArray_Newshape。为了向后兼容——不推荐。

PyObject *PyArray_Squeeze(PyArrayObject *self)#

等效于 ndarray.squeeze (self)。返回self的新视图,其中长度为1的所有维度都已从形状中移除。

警告

矩阵对象始终是二维的。因此,PyArray_Squeeze 对矩阵子类的数组没有影响。

PyObject *PyArray_SwapAxes(PyArrayObject *self, int a1, int a2)#

等效于 ndarray.swapaxes (self, a1, a2)。返回的数组是self中数据的新的视图,其中给定的轴a1a2已交换。

PyObject *PyArray_Resize(PyArrayObject *self, PyArray_Dims *newshape, int refcheck, NPY_ORDER fortran)#

等效于 ndarray.resize (self, newshape, refcheck = refcheck, order= fortran)。此函数仅适用于单段数组。它会就地更改self的形状,如果newshape的元素总数与旧形状不同,则会重新分配self的内存。如果需要重新分配,则self必须拥有其数据,具有self - >base==NULL,具有self - >weakrefs==NULL,并且(除非refcheck为0)不被任何其他数组引用。fortran参数可以是NPY_ANYORDERNPY_CORDERNPY_FORTRANORDER。它目前没有任何作用。最终它可以用来确定在构造不同维度的数组时,调整大小操作应该如何查看数据。成功时返回None,错误时返回NULL。

PyObject *PyArray_Transpose(PyArrayObject *self, PyArray_Dims *permute)#

等效于 ndarray.transpose (self, permute)。根据数据结构permute置换ndarray对象self的轴,并返回结果。如果permuteNULL,则结果数组的轴将反转。例如,如果self的形状为\(10\times20\times30\),而permute .ptr为(0,2,1),则结果的形状为\(10\times30\times20.\)如果permuteNULL,则结果的形状为\(30\times20\times10.\)

PyObject *PyArray_Flatten(PyArrayObject *self, NPY_ORDER order)#

等效于 ndarray.flatten (self, order)。返回数组的一维副本。如果orderNPY_FORTRANORDER,则元素按Fortran顺序扫描(第一维变化最快)。如果orderNPY_CORDER,则self的元素按C顺序扫描(最后一维变化最快)。如果orderNPY_ANYORDER,则使用PyArray_ISFORTRAN (self) 的结果来确定展平的顺序。

PyObject *PyArray_Ravel(PyArrayObject *self, NPY_ORDER order)#

等效于self.ravel(order)。与PyArray_Flatten (self, order) 的基本功能相同,但如果order为0且self为C风格连续的,则形状会改变,但不会执行复制。

元素选择和操作#

PyObject *PyArray_TakeFrom(PyArrayObject *self, PyObject *indices, int axis, PyArrayObject *ret, NPY_CLIPMODE clipmode)#

等效于 ndarray.take (self, indices, axis, ret, clipmode),除了Python中的axis = None可以通过在C中设置axis = NPY_MAXDIMS 来获得。沿着给定的axis提取由整数值indices指示的self中的元素。clipmode参数可以是NPY_RAISENPY_WRAPNPY_CLIP,以指示如何处理越界索引。ret参数可以指定输出数组,而不是内部创建的数组。

PyObject *PyArray_PutTo(PyArrayObject *self, PyObject *values, PyObject *indices, NPY_CLIPMODE clipmode)#

等效于self.put(values, indices, clipmode)。将values放入self中对应的(展平的)indices位置。如果values太小,则会根据需要重复。

PyObject *PyArray_PutMask(PyArrayObject *self, PyObject *values, PyObject *mask)#

mask中对应位置(使用展平的上下文)为真的地方,将values放入self中。maskself数组必须具有相同的元素总数。如果values太小,则会根据需要重复。

PyObject *PyArray_Repeat(PyArrayObject *self, PyObject *op, int axis)#

等效于 ndarray.repeat (self, op, axis)。沿着给定的axis复制self的元素op次。op要么是一个标量整数,要么是一个长度为self->dimensions[ axis ]的序列,指示沿该轴重复每个项目多少次。

PyObject *PyArray_Choose(PyArrayObject *self, PyObject *op, PyArrayObject *ret, NPY_CLIPMODE clipmode)#

等效于 ndarray.choose (self, op, ret, clipmode)。根据self中的整数值,从op中的数组序列中选择元素,创建一个新数组。这些数组必须全部可广播到相同的形状,并且self中的条目应在0到len(op)之间。输出放在ret中,除非它是NULL,在这种情况下会创建一个新的输出。clipmode参数决定当self中的条目不在0到len(op)之间时的行为。

NPY_RAISE#

引发ValueError;

NPY_WRAP#

将小于 0 的值加上 len(op),将大于等于 len(op) 的值减去 len(op),直到值在范围内;

NPY_CLIP#

所有值都被裁剪到 [0, len(op) ) 范围内。

PyObject *PyArray_Sort(PyArrayObject *self, int axis, NPY_SORTKIND kind)#

等效于 ndarray.sort (self, axis, kind)。返回一个数组,其中包含沿 *axis* 排序的 *self* 的项目。该数组使用由 *kind* 表示的算法进行排序,*kind* 是一个整数/枚举,指向所使用的排序算法的类型。

PyObject *PyArray_ArgSort(PyArrayObject *self, int axis)#

等效于 ndarray.argsort (self, axis)。返回一个索引数组,使得沿给定 axis 选择这些索引将返回 *self* 的排序版本。如果 *self* ->descr 是一个定义了字段的数据类型,则 self->descr->names 用于确定排序顺序。第一个字段相等的比较将使用第二个字段,依此类推。要更改结构化数组的排序顺序,请创建一个具有不同名称顺序的新数据类型,并使用该新数据类型构造数组的视图。

PyObject *PyArray_LexSort(PyObject *sort_keys, int axis)#

给定一系列相同形状的数组 (*sort_keys*),返回一个索引数组(类似于 PyArray_ArgSort (…)),该数组将按字典顺序对数组进行排序。字典排序指定当发现两个键相等时,顺序基于后续键的比较。需要为类型定义合并排序(它使相等条目保持不动)。排序是通过首先使用第一个 *sort_key* 对索引进行排序,然后使用第二个 *sort_key*,依此类推来完成的。这等效于 lexsort(*sort_keys*, *axis*) Python 命令。由于合并排序的工作方式,请务必了解 *sort_keys* 必须具有的顺序(与比较两个元素时使用的顺序相反)。

如果所有这些数组都收集在一个结构化数组中,则还可以使用 PyArray_Sort (…) 直接对数组进行排序。

PyObject *PyArray_SearchSorted(PyArrayObject *self, PyObject *values, NPY_SEARCHSIDE side, PyObject *perm)#

等效于 ndarray.searchsorted (self, values, side, perm)。假设 *self* 是一个升序排列的一维数组,则输出是一个与 *values* 形状相同的索引数组,使得如果将 *values* 中的元素插入到索引之前,则 *self* 的顺序将保持不变。不会检查 *self* 是否升序排列。

*side* 参数指示返回的索引应该是第一个合适位置的索引(如果为 NPY_SEARCHLEFT)还是最后一个合适位置的索引(如果为 NPY_SEARCHRIGHT)。

如果 *sorter* 参数不是 NULL,则它必须是一个与 *self* 长度相同的一维整数索引数组,该数组将其排序为升序。这通常是调用 PyArray_ArgSort (…) 的结果。二分查找用于查找所需的插入点。

int PyArray_Partition(PyArrayObject *self, PyArrayObject *ktharray, int axis, NPY_SELECTKIND which)#

等效于 ndarray.partition (self, ktharray, axis, kind)。对数组进行分区,以便由 *ktharray* 索引的元素的值位于如果数组完全排序则它们所在的位置,并将所有小于第 k 个元素的元素放在前面,并将所有等于或大于第 k 个元素的元素放在后面。所有分区内元素的顺序是未定义的。如果 *self*->descr 是一个定义了字段的数据类型,则 self->descr->names 用于确定排序顺序。第一个字段相等的比较将使用第二个字段,依此类推。要更改结构化数组的排序顺序,请创建一个具有不同名称顺序的新数据类型,并使用该新数据类型构造数组的视图。成功返回零,失败返回 -1。

PyObject *PyArray_ArgPartition(PyArrayObject *op, PyArrayObject *ktharray, int axis, NPY_SELECTKIND which)#

等效于 ndarray.argpartition (self, ktharray, axis, kind)。返回一个索引数组,使得沿给定 axis 选择这些索引将返回 *self* 的分区版本。

PyObject *PyArray_Diagonal(PyArrayObject *self, int offset, int axis1, int axis2)#

等效于 ndarray.diagonal (self, offset, axis1, axis2 )。返回由 *axis1* 和 *axis2* 定义的二维数组的 *offset* 对角线。

npy_intp PyArray_CountNonzero(PyArrayObject *self)#

计算数组对象 *self* 中非零元素的数量。

PyObject *PyArray_Nonzero(PyArrayObject *self)#

等价于 ndarray.nonzero (self)。返回一个索引数组元组,选择自身中非零元素。如果 (nd= PyArray_NDIM ( self ))==1,则返回单个索引数组。索引数组的数据类型为 NPY_INTP。如果返回元组 (nd \(\neq\) 1),则其长度为 nd。

PyObject *PyArray_Compress(PyArrayObject *self, PyObject *condition, int axis, PyArrayObject *out)#

等价于 ndarray.compress (self, condition, axis )。返回沿 *axis* 对应于 *condition* 中为真的元素的元素。

计算#

提示

为了获得与在 Python 中传入 axis=None (将数组视为一维数组) 相同的效果,请将 NPY_RAVEL_AXIS 传递给 axis。

注意

out 参数指定放置结果的位置。如果 out 为 NULL,则创建输出数组,否则将输出放置在 out 中,out 必须具有正确的尺寸和类型。即使 out 不为 NULL,也会始终返回对输出数组的新引用。如果 out 不为 NULL,则例程的调用者有责任 Py_DECREF out,否则会发生内存泄漏。

PyObject *PyArray_ArgMax(PyArrayObject *self, int axis, PyArrayObject *out)#

等价于 ndarray.argmax (self, axis)。返回自身沿 *axis* 的最大元素的索引。

PyObject *PyArray_ArgMin(PyArrayObject *self, int axis, PyArrayObject *out)#

等价于 ndarray.argmin (self, axis)。返回自身沿 *axis* 的最小元素的索引。

PyObject *PyArray_Max(PyArrayObject *self, int axis, PyArrayObject *out)#

等价于 ndarray.max (self, axis)。返回自身沿给定 *axis* 的最大元素。当结果为单个元素时,返回 numpy 标量而不是 ndarray。

PyObject *PyArray_Min(PyArrayObject *self, int axis, PyArrayObject *out)#

等价于 ndarray.min (self, axis)。返回自身沿给定 *axis* 的最小元素。当结果为单个元素时,返回 numpy 标量而不是 ndarray。

PyObject *PyArray_Ptp(PyArrayObject *self, int axis, PyArrayObject *out)#

返回自身沿 *axis* 的最大元素与自身沿 *axis* 的最小元素之间的差值。当结果为单个元素时,返回 numpy 标量而不是 ndarray。

注意

rtype 参数指定应在其上进行约简的数据类型。如果数组的数据类型不足以处理输出,这一点很重要。“add”和“multiply”ufunc(构成 mean、sum、cumsum、prod 和 cumprod 函数的基础)默认情况下,所有整数数据类型都至少与 NPY_LONG 一样大。

PyObject *PyArray_Mean(PyArrayObject *self, int axis, int rtype, PyArrayObject *out)#

等价于 ndarray.mean (self, axis, rtype)。返回沿给定 *axis* 的元素的平均值,使用枚举类型 *rtype* 作为求和的数据类型。使用 NPY_NOTYPE 作为 *rtype* 可以获得默认的求和行为。

PyObject *PyArray_Trace(PyArrayObject *self, int offset, int axis1, int axis2, int rtype, PyArrayObject *out)#

等效于 ndarray.trace (self, offset, axis1, axis2, rtype)。返回由axis1axis2变量定义的二维数组的offset对角线元素之和(使用rtype作为求和的数据类型)。正偏移量选择主对角线以上的对角线。负偏移量选择主对角线以下的对角线。

PyObject *PyArray_Clip(PyArrayObject *self, PyObject *min, PyObject *max)#

等效于 ndarray.clip (self, min, max)。裁剪数组self,使得大于max的值被固定为max,小于min的值被固定为min

PyObject *PyArray_Conjugate(PyArrayObject *self, PyArrayObject *out)#

等效于 ndarray.conjugate (self)。返回self的复共轭。如果self不是复数数据类型,则返回对self的引用。

参数:
  • self – 输入数组。

  • out – 输出数组。如果提供,结果将放入此数组。

返回:

self的复共轭。

PyObject *PyArray_Round(PyArrayObject *self, int decimals, PyArrayObject *out)#

等效于 ndarray.round (self, decimals, out)。返回元素四舍五入到最近小数位的数组。小数位定义为\(10^{-\textrm{decimals}}\)位,因此负decimals会导致四舍五入到最接近的10、100等。如果out为NULL,则创建输出数组,否则输出将放在out中,out必须具有正确的尺寸和类型。

PyObject *PyArray_Std(PyArrayObject *self, int axis, int rtype, PyArrayObject *out)#

等效于 ndarray.std (self, axis, rtype)。返回使用沿axis转换到数据类型rtype的数据计算的标准差。

PyObject *PyArray_Sum(PyArrayObject *self, int axis, int rtype, PyArrayObject *out)#

等效于 ndarray.sum (self, axis, rtype)。返回self中沿axis的元素的一维向量和。在将数据转换为数据类型rtype后执行求和。

PyObject *PyArray_CumSum(PyArrayObject *self, int axis, int rtype, PyArrayObject *out)#

等效于 ndarray.cumsum (self, axis, rtype)。返回self中沿axis的元素的一维累积和。在将数据转换为数据类型rtype后执行求和。

PyObject *PyArray_Prod(PyArrayObject *self, int axis, int rtype, PyArrayObject *out)#

等效于 ndarray.prod (self, axis, rtype)。返回self中沿axis的元素的一维乘积。在将数据转换为数据类型rtype后执行乘积。

PyObject *PyArray_CumProd(PyArrayObject *self, int axis, int rtype, PyArrayObject *out)#

等效于 ndarray.cumprod (self, axis, rtype)。返回self沿axis的元素的一维累积乘积。在将数据转换为数据类型rtype后执行乘积。

PyObject *PyArray_All(PyArrayObject *self, int axis, PyArrayObject *out)#

等效于 ndarray.all (self, axis)。返回一个数组,其中对于由axis定义的self的每个一维子数组,如果所有元素都为True,则其元素为True。

PyObject *PyArray_Any(PyArrayObject *self, int axis, PyArrayObject *out)#

等效于 ndarray.any (self, axis)。返回一个数组,其中对于由 *axis* 定义的 *self* 的每个一维子数组,如果其中任何元素为 True,则其对应元素为 True。

函数#

数组函数#

int PyArray_AsCArray(PyObject **op, void *ptr, npy_intp *dims, int nd, PyArray_Descr *typedescr)#

有时,将多维数组作为 C 样式多维数组访问非常有用,以便可以使用 C 的 a[i][j][k] 语法实现算法。此例程返回一个指针 *ptr*,它模拟这种 C 样式数组,用于一维、二维和三维 ndarray。

参数:
  • op – 任何 Python 对象的地址。此 Python 对象将被替换为等效的、行为良好的、C 样式连续的、具有由最后两个参数指定的数据类型的 ndarray。请确保以这种方式窃取对输入对象的引用是合理的。

  • ptr – 指向 (对于一维为 ctype*,对于二维为 ctype**,对于三维为 ctype***) 变量的地址,其中 ctype 是数据类型的等效 C 类型。返回时,*ptr* 将可寻址为一维、二维或三维数组。

  • dims – 包含数组对象形状的输出数组。此数组为将进行的任何循环设置边界。

  • nd – 数组的维数 (1、2 或 3)。

  • typedescr – 一个 PyArray_Descr 结构,指示所需的数据类型(包括所需的字节序)。此调用将窃取对参数的引用。

注意

对于二维和三维数组,C 样式数组的模拟并不完整。例如,指向指针的模拟数组不能传递给期望特定静态定义的二维和三维数组的子例程。要传递给需要此类输入的函数,必须静态定义所需的数组并复制数据。

int PyArray_Free(PyObject *op, void *ptr)#

必须使用 PyArray_AsCArray (…) 返回的相同对象和内存位置调用。此函数清理否则会泄漏的内存。

PyObject *PyArray_Concatenate(PyObject *obj, int axis)#

沿 *axis* 将 *obj* 中的对象序列连接到单个数组中。如果维度或类型不兼容,则会引发错误。

PyObject *PyArray_InnerProduct(PyObject *obj1, PyObject *obj2)#

计算 *obj1* 和 *obj2* 的最后几维上的乘积和。不共轭任何数组。

PyObject *PyArray_MatrixProduct(PyObject *obj1, PyObject *obj)#

计算 *obj1* 的最后维度和 *obj2* 的倒数第二维度上的乘积和。对于二维数组,这是矩阵乘积。不共轭任何数组。

PyObject *PyArray_MatrixProduct2(PyObject *obj1, PyObject *obj, PyArrayObject *out)#

与 PyArray_MatrixProduct 相同,但将结果存储在 *out* 中。输出数组必须具有正确的形状、类型并且是 C 连续的,否则会引发异常。

PyArrayObject *PyArray_EinsteinSum(char *subscripts, npy_intp nop, PyArrayObject **op_in, PyArray_Descr *dtype, NPY_ORDER order, NPY_CASTING casting, PyArrayObject *out)#

将爱因斯坦求和约定应用于提供的数组操作数,返回一个新数组或将结果放在 *out* 中。*subscripts* 中的字符串是一个用逗号分隔的索引字母列表。操作数的数量在 *nop* 中,而 *op_in* 是一个包含这些操作数的数组。可以使用 *dtype* 强制输出的数据类型,可以使用 *order* 强制输出顺序(推荐使用 NPY_KEEPORDER),当指定 *dtype* 时,*casting* 指示数据转换的允许程度。

有关更多详细信息,请参阅 einsum 函数。

PyObject *PyArray_Correlate(PyObject *op1, PyObject *op2, int mode)#

计算一维数组op1op2的一维相关性。相关性通过将op1op2的移位版本相乘并求和来计算每个输出点。由于移位,op1op2定义范围之外所需的数值将被解释为零。模式决定返回多少个移位:0 - 只返回不需要假设零值的移位;1 - 返回与op1大小相同的对象;2 - 返回所有可能的移位(任何重叠都被接受)。

注释

这不会计算通常的相关性:如果op2大于op1,则参数将被交换,并且对于复数数组永远不会取共轭。有关通常的信号处理相关性,请参阅PyArray_Correlate2。

PyObject *PyArray_Correlate2(PyObject *op1, PyObject *op2, int mode)#

PyArray_Correlate的更新版本,它使用一维数组相关性的常用定义。相关性通过将op1op2的移位版本相乘并求和来计算每个输出点。由于移位,op1op2定义范围之外所需的数值将被解释为零。模式决定返回多少个移位:0 - 只返回不需要假设零值的移位;1 - 返回与op1大小相同的对象;2 - 返回所有可能的移位(任何重叠都被接受)。

注释

计算z如下:

z[k] = sum_n op1[n] * conj(op2[n+k])
PyObject *PyArray_Where(PyObject *condition, PyObject *x, PyObject *y)#

如果xy都为NULL,则返回PyArray_Nonzero(condition)。否则,必须给出xy,返回的对象形状与condition相同,并在condition分别为True或False的地方具有xy的元素。

其他函数#

npy_bool PyArray_CheckStrides(int elsize, int nd, npy_intp numbytes, npy_intp const *dims, npy_intp const *newstrides)#

确定newstrides是否是一个步长数组,该数组与具有形状dims和元素大小elsizend维数组的内存一致。检查newstrides数组,以查看在每个方向上跳跃提供的字节数是否意味着跳跃超过numbytes(这是可用内存段的假定大小)。如果numbytes为0,则假设nddimselsize指的是单个段数组来计算等效的numbytes。如果newstrides可接受,则返回NPY_TRUE;否则,返回NPY_FALSE

npy_intp PyArray_MultiplyList(npy_intp const *seq, int n)#
int PyArray_MultiplyIntList(int const *seq, int n)#

这两个例程都将长度为n的整数数组seq相乘并返回结果。不执行溢出检查。

int PyArray_CompareLists(npy_intp const *l1, npy_intp const *l2, int n)#

给定两个长度为n的整数数组l1l2,如果列表相同,则返回1;否则,返回0。

具有对象语义的辅助数据#

type NpyAuxData#

当处理由其他dtype组成的更复杂的dtype(例如struct dtype)时,创建操作dtype的内部循环需要携带附加数据。NumPy通过结构体NpyAuxData支持这个想法,强制执行一些约定,以便可以做到这一点。

定义NpyAuxData类似于在C++中定义类,但是必须手动跟踪对象语义,因为API是在C中。

typedef struct {
    NpyAuxData base;
    ElementCopier_Func *func;
    NpyAuxData *funcdata;
} eldoubler_aux_data;

void free_element_doubler_aux_data(NpyAuxData *data)
{
    eldoubler_aux_data *d = (eldoubler_aux_data *)data;
    /* Free the memory owned by this auxdata */
    NPY_AUXDATA_FREE(d->funcdata);
    PyArray_free(d);
}

NpyAuxData *clone_element_doubler_aux_data(NpyAuxData *data)
{
    eldoubler_aux_data *ret = PyArray_malloc(sizeof(eldoubler_aux_data));
    if (ret == NULL) {
        return NULL;
    }

    /* Raw copy of all data */
    memcpy(ret, data, sizeof(eldoubler_aux_data));

    /* Fix up the owned auxdata so we have our own copy */
    ret->funcdata = NPY_AUXDATA_CLONE(ret->funcdata);
    if (ret->funcdata == NULL) {
        PyArray_free(ret);
        return NULL;
    }

    return (NpyAuxData *)ret;
}

NpyAuxData *create_element_doubler_aux_data(
                            ElementCopier_Func *func,
                            NpyAuxData *funcdata)
{
    eldoubler_aux_data *ret = PyArray_malloc(sizeof(eldoubler_aux_data));
    if (ret == NULL) {
        PyErr_NoMemory();
        return NULL;
    }
    memset(&ret, 0, sizeof(eldoubler_aux_data));
    ret->base->free = &free_element_doubler_aux_data;
    ret->base->clone = &clone_element_doubler_aux_data;
    ret->func = func;
    ret->funcdata = funcdata;

    return (NpyAuxData *)ret;
}
type NpyAuxData_FreeFunc#

NpyAuxData释放函数的函数指针类型。

type NpyAuxData_CloneFunc#

NpyAuxData克隆函数的函数指针类型。这些函数决不应该在错误时设置Python异常,因为它们可能从多线程上下文中调用。

void NPY_AUXDATA_FREE(NpyAuxData *auxdata)#

一个宏,它适当地调用辅助数据的释放函数,如果 auxdata 为 NULL,则不执行任何操作。

NpyAuxData *NPY_AUXDATA_CLONE(NpyAuxData *auxdata)#

一个宏,它适当地调用辅助数据的克隆函数,返回辅助数据的深拷贝。

数组迭代器#

从 NumPy 1.6.0 开始,这些数组迭代器已被新的数组迭代器 NpyIter 取代。

数组迭代器是一种快速有效地访问 N 维数组元素的简单方法,如 示例 所示,该示例更详细地描述了这种在 C 中遍历数组的有用方法。

PyObject *PyArray_IterNew(PyObject *arr)#

从数组 *arr* 返回一个数组迭代器对象。这等效于 *arr*.**flat**。数组迭代器对象使在 C 中以 C 样式连续的方式轻松遍历 N 维非连续数组。

PyObject *PyArray_IterAllButAxis(PyObject *arr, int *axis)#

返回一个数组迭代器,它将迭代除在 *axis* 中提供的轴之外的所有轴。返回的迭代器不能与 PyArray_ITER_GOTO1D 一起使用。此迭代器可用于编写类似于 ufunc 的内容,其中对最大轴的循环由单独的子例程执行。如果 *axis* 为负数,则 *axis* 将设置为具有最小步长的轴,并将使用该轴。

PyObject *PyArray_BroadcastToShape(PyObject *arr, npy_intp const *dimensions, int nd)#

返回一个数组迭代器,该迭代器被广播以迭代为由 *dimensions* 和 *nd* 提供的形状的数组。

int PyArrayIter_Check(PyObject *op)#

如果 *op* 是数组迭代器(或数组迭代器类型的子类的实例),则评估为真。

void PyArray_ITER_RESET(PyObject *iterator)#

将 *iterator* 重置到数组的开头。

void PyArray_ITER_NEXT(PyObject *iterator)#

递增 *iterator* 的索引和 dataptr 成员,以指向数组的下一个元素。如果数组不是(C 样式)连续的,则还递增 N 维坐标数组。

void *PyArray_ITER_DATA(PyObject *iterator)#

指向数组当前元素的指针。

void PyArray_ITER_GOTO(PyObject *iterator, npy_intp *destination)#

将 *iterator* 的索引、dataptr 和坐标成员设置为由 N 维 c 数组 *destination* 指示的数组中的位置,该数组的大小必须至少为 *iterator* ->nd_m1+1。

void PyArray_ITER_GOTO1D(PyObject *iterator, npy_intp index)#

将 *iterator* 的索引和 dataptr 设置为由整数 *index* 指示的数组中的位置,该整数指向 C 样式扁平化数组中的元素。

int PyArray_ITER_NOTDONE(PyObject *iterator)#

只要迭代器尚未遍历所有元素,则评估为 TRUE,否则评估为 FALSE。

广播(多迭代器)#

PyObject *PyArray_MultiIterNew(int num, ...)#

广播的简化接口。此函数获取要广播的数组数量,然后获取 *num* 个额外的(PyObject *)参数。这些参数被转换为数组,并创建迭代器。PyArray_Broadcast 然后在生成的多分支迭代器对象上被调用。然后返回生成的广播多分支迭代器对象。然后可以使用单个循环和 PyArray_MultiIter_NEXT (..) 执行广播操作。

void PyArray_MultiIter_RESET(PyObject *multi)#

将多分支迭代器对象 *multi* 中的所有迭代器重置到开头。

void PyArray_MultiIter_NEXT(PyObject *multi)#

将多分支迭代器对象 *multi* 中的每个迭代器推进到其下一个(广播的)元素。

void *PyArray_MultiIter_DATA(PyObject *multi, int i)#

返回多迭代器对象中第 i 个迭代器的数\(^{\textrm{th}}\)据指针。

void PyArray_MultiIter_NEXTi(PyObject *multi, int i)#

仅推进第 i \(^{\textrm{th}}\) 个迭代器的指针。

void PyArray_MultiIter_GOTO(PyObject *multi, npy_intp *destination)#

将多迭代器对象 multi 中的每个迭代器推进到给定的 \(N\)destination,其中 \(N\) 是广播数组的维数。

void PyArray_MultiIter_GOTO1D(PyObject *multi, npy_intp index)#

将多迭代器对象 multi 中的每个迭代器推进到展平的广播数组中 index 对应的位置。

int PyArray_MultiIter_NOTDONE(PyObject *multi)#

只要多迭代器没有遍历所有元素(广播结果的元素),就评估为 TRUE;否则评估为 FALSE。

npy_intp PyArray_MultiIter_SIZE(PyArrayMultiIterObject *multi)#

1.26.0 版的新功能。

返回多迭代器对象的总广播大小。

int PyArray_MultiIter_NDIM(PyArrayMultiIterObject *multi)#

1.26.0 版的新功能。

返回多迭代器对象广播结果的维数。

npy_intp PyArray_MultiIter_INDEX(PyArrayMultiIterObject *multi)#

1.26.0 版的新功能。

返回多迭代器对象广播结果的当前(一维)索引。

int PyArray_MultiIter_NUMITER(PyArrayMultiIterObject *multi)#

1.26.0 版的新功能。

返回多迭代器对象表示的迭代器数量。

void **PyArray_MultiIter_ITERS(PyArrayMultiIterObject *multi)#

1.26.0 版的新功能。

返回一个迭代器对象数组,该数组保存要一起广播的数组的迭代器。返回时,迭代器将针对广播进行调整。

npy_intp *PyArray_MultiIter_DIMS(PyArrayMultiIterObject *multi)#

1.26.0 版的新功能。

返回指向多迭代器对象广播结果的维度/形状的指针。

int PyArray_Broadcast(PyArrayMultiIterObject *mit)#

此函数封装了广播规则。mit 容器应已包含所有需要广播的数组的迭代器。返回时,这些迭代器将被调整,以便同时迭代每个迭代器将完成广播。如果发生错误,则返回负数。

int PyArray_RemoveSmallest(PyArrayMultiIterObject *mit)#

此函数采用一个先前已“广播”的多迭代器对象,找到广播结果中“步幅之和”最小的维度,并调整所有迭代器,以便不迭代该维度(通过有效地使它们在该维度上的长度为 1)。除非 mit ->nd 为 0,否则返回相应的维度,否则返回 -1。此函数对于构建类似 ufunc 的例程非常有用,这些例程可以正确广播其输入,然后将例程的带步幅的一维版本作为内循环调用。此一维版本通常针对速度进行了优化,因此应在不需要大型步幅跳跃的轴上执行循环。

邻域迭代器#

邻域迭代器是迭代器对象的子类,可用于迭代点的邻域。例如,您可能希望迭代 3D 图像的每个体素,并且对于每个这样的体素,迭代一个超立方体。邻域迭代器自动处理边界,因此使这种类型的代码比手动边界处理更容易编写,但代价是略微的开销。

PyObject *PyArray_NeighborhoodIterNew(PyArrayIterObject *iter, npy_intp bounds, int mode, PyArrayObject *fill_value)#

此函数根据现有迭代器创建一个新的邻域迭代器。邻域将相对于 iter 当前指向的位置计算,边界定义邻域迭代器的形状,模式参数定义边界处理模式。

bounds 参数应为 (2 * iter->ao->nd) 数组,例如范围 bound[2*i]->bounds[2*i+1] 定义了维度 i 的遍历范围(两个边界都包含在遍历坐标中)。边界应针对每个维度进行排序 (bounds[2*i] <= bounds[2*i+1])。

模式应为以下之一:

NPY_NEIGHBORHOOD_ITER_ZERO_PADDING#

零填充。边界外值为0。

NPY_NEIGHBORHOOD_ITER_ONE_PADDING#

一填充,边界外值为1。

NPY_NEIGHBORHOOD_ITER_CONSTANT_PADDING#

常量填充。边界外值与`fill_value`中的第一个元素相同。

NPY_NEIGHBORHOOD_ITER_MIRROR_PADDING#

镜像填充。边界外值如同数组元素被镜像一样。例如,对于数组[1, 2, 3, 4],x[-2] 将为 2,x[-1] 将为 1,x[4] 将为 4,x[5] 将为 1,等等…

NPY_NEIGHBORHOOD_ITER_CIRCULAR_PADDING#

循环填充。边界外值如同数组被重复一样。例如,对于数组[1, 2, 3, 4],x[-2] 将为 3,x[-1] 将为 4,x[4] 将为 1,x[5] 将为 2,等等…

如果模式为常量填充(NPY_NEIGHBORHOOD_ITER_CONSTANT_PADDING),`fill_value` 应该指向一个数组对象,该对象保存填充值(如果数组包含多个元素,则第一个元素为填充值)。对于其他情况,`fill_value` 可以为 NULL。

  • 迭代器持有对`iter`的引用。

  • 失败时返回 NULL(在这种情况下,`iter` 的引用计数不会改变)。

  • `iter` 本身可以是一个邻域迭代器:这对于例如自动边界处理很有用。

  • 此函数返回的对象应该可以安全地用作普通迭代器。

  • 如果`iter`的位置发生改变,任何后续对`PyArrayNeighborhoodIter_Next`的调用都是未定义的行为,必须调用`PyArrayNeighborhoodIter_Reset`。

  • 如果`iter`的位置不是数据的开头,并且`iter`的基础数据是连续的,则迭代器将指向数据的开头,而不是`iter`指向的位置。为避免这种情况,只有在创建迭代器之后才能将`iter`移动到所需位置,并且必须调用`PyArrayNeighborhoodIter_Reset`。

PyArrayIterObject *iter;
PyArrayNeighborhoodIterObject *neigh_iter;
iter = PyArray_IterNew(x);

/*For a 3x3 kernel */
bounds = {-1, 1, -1, 1};
neigh_iter = (PyArrayNeighborhoodIterObject*)PyArray_NeighborhoodIterNew(
     iter, bounds, NPY_NEIGHBORHOOD_ITER_ZERO_PADDING, NULL);

for(i = 0; i < iter->size; ++i) {
     for (j = 0; j < neigh_iter->size; ++j) {
             /* Walk around the item currently pointed by iter->dataptr */
             PyArrayNeighborhoodIter_Next(neigh_iter);
     }

     /* Move to the next point of iter */
     PyArrayIter_Next(iter);
     PyArrayNeighborhoodIter_Reset(neigh_iter);
}
int PyArrayNeighborhoodIter_Reset(PyArrayNeighborhoodIterObject *iter)#

将迭代器位置重置到邻域的第一个点。每当更改`PyArray_NeighborhoodIterObject`中提供的`iter`参数时,都应该调用此函数(参见示例)。

int PyArrayNeighborhoodIter_Next(PyArrayNeighborhoodIterObject *iter)#

此调用之后,`iter->dataptr` 指向邻域的下一个点。在访问完邻域的每个点之后调用此函数是未定义的。

数组标量#

PyObject *PyArray_Return(PyArrayObject *arr)#

此函数窃取对`arr`的引用。

此函数检查`arr`是否为 0 维数组,如果是,则返回相应的数组标量。每当可能将 0 维数组返回到 Python 时,都应使用它。

PyObject *PyArray_Scalar(void *data, PyArray_Descr *dtype, PyObject *base)#

通过**复制**`data`指向的内存中的数据,返回给定`dtype`的数组标量对象。如果`dtype`是`void`标量,或者设置了`NPY_USE_GETITEM`标志并且已知`getitem`方法使用了`arr`参数而没有检查它是否为`NULL`,则`base`应为数组对象,它是数据的拥有者。否则,`base`可以为`NULL`。

如果数据不是本机字节序(由`dtype->byteorder`指示),则此函数将交换数据字节序,因为数组标量始终采用正确的机器字节序。

PyObject *PyArray_ToScalar(void *data, PyArrayObject *arr)#

返回由数组对象`arr`指示的类型和项目大小的数组标量对象,该对象从`data`指向的内存复制而来,如果`arr`中的数据不是机器字节序,则进行字节交换。

PyObject *PyArray_FromScalar(PyObject *scalar, PyArray_Descr *outcode)#

从`scalar`(它应该是数组标量对象)返回由`outcode`确定的类型的 0 维数组。如果`outcode`为 NULL,则类型由`scalar`确定。

void PyArray_ScalarAsCtype(PyObject *scalar, void *ctypeptr)#

在`ctypeptr`中返回指向数组标量中实际值的指针。没有错误检查,因此`scalar`必须是数组标量对象,并且`ctypeptr`必须有足够的空间来容纳正确的类型。对于大小灵活的类型,将指向数据的指针复制到`ctypeptr`的内存中;对于所有其他类型,将实际数据复制到`ctypeptr`指向的地址。

int PyArray_CastScalarToCtype(PyObject *scalar, void *ctypeptr, PyArray_Descr *outcode)#

将数组标量`scalar`中的数据(转换为`outcode`指示的数据类型)返回到`ctypeptr`指向的内存(必须足够大以处理传入的内存)。

失败时返回 -1,成功时返回 0。

PyObject *PyArray_TypeObjectFromType(int type)#

从类型编号 *type* 返回一个标量类型对象。等效于 PyArray_DescrFromType (type)->typeobj,除了引用计数和错误检查。成功时返回类型对象的新引用,失败时返回 NULL

NPY_SCALARKIND PyArray_ScalarKind(int typenum, PyArrayObject **arr)#

查询标量值的特殊提升的传统方法。NumPy 本身不再使用此方法,预计最终会被弃用。

新的 DType 可以定义特定于 Python 标量的提升规则。

int PyArray_CanCoerceScalar(char thistype, char neededtype, NPY_SCALARKIND scalar)#

查询标量值的特殊提升的传统方法。NumPy 本身不再使用此方法,预计最终会被弃用。

出于类似目的,请使用 PyArray_ResultType

数据类型描述符#

警告

数据类型对象必须进行引用计数,因此请注意不同 C-API 调用对数据类型引用的操作。标准规则是,当返回数据类型对象时,它是一个新的引用。除非另有说明,否则采用 PyArray_Descr* 对象并返回数组的函数会窃取其输入的数据类型的引用。因此,您必须拥有用作此类函数输入的任何数据类型对象的引用。

int PyArray_DescrCheck(PyObject *obj)#

如果 *obj* 是数据类型对象(PyArray_Descr*),则评估结果为真。

PyArray_Descr *PyArray_DescrNew(PyArray_Descr *obj)#

返回从 *obj* 复制的新数据类型对象(字段引用仅更新,以便新对象指向相同的字段字典,如果有的话)。

PyArray_Descr *PyArray_DescrNewFromType(int typenum)#

根据 *typenum* 指示的内置(或用户注册的)数据类型创建一个新的数据类型对象。所有内置类型都不应更改其任何字段。这会创建 PyArray_Descr 结构的新副本,以便您可以根据需要填充它。此函数对于需要具有新的 elsize 成员才能在数组构造中具有意义的灵活数据类型尤其必要。

PyArray_Descr *PyArray_DescrNewByteorder(PyArray_Descr *obj, char newendian)#

创建一个新的数据类型对象,其字节序根据 *newendian* 设置。所有引用的数据类型对象(在数据类型对象的 subdescr 和 fields 成员中)也会更改(递归)。

*newendian* 的值是以下宏之一

NPY_IGNORE#
NPY_SWAP#
NPY_NATIVE#
NPY_LITTLE#
NPY_BIG#

如果遇到 NPY_IGNORE 的字节序,则将其保留。如果 newendian 为 NPY_SWAP,则所有字节序都将交换。其他有效 newendian 值为 NPY_NATIVENPY_LITTLENPY_BIG,它们都会导致返回的数据类型描述符(及其所有引用的数据类型描述符)具有相应的字节序。

PyArray_Descr *PyArray_DescrFromObject(PyObject *op, PyArray_Descr *mintype)#

根据对象 *op*(应该是“嵌套”序列对象)和最小数据类型描述符 mintype(可以为 NULL)确定适当的数据类型对象。其行为类似于 array(op).dtype。不要将此函数与 PyArray_DescrConverter 混淆。此函数基本上会查看(嵌套)序列中的所有对象,并根据找到的元素确定数据类型。

PyArray_Descr *PyArray_DescrFromScalar(PyObject *scalar)#

从数组标量对象返回数据类型对象。不会执行任何检查以确保 *scalar* 是数组标量。如果无法确定合适的数据类型,则默认情况下返回 NPY_OBJECT 数据类型。

PyArray_Descr *PyArray_DescrFromType(int typenum)#

返回与 *typenum* 对应的类型对象。*typenum* 可以是枚举类型之一,枚举类型之一的字符代码,或用户定义类型。如果要使用灵活大小的数组,则需要 flexible typenum 并将结果 elsize 参数设置为所需大小。typenum 是 NPY_TYPES 之一。

int PyArray_DescrConverter(PyObject *obj, PyArray_Descr **dtype)#

将任何兼容的 Python 对象 *obj* 转换为 *dtype* 中的数据类型对象。许多 Python 对象可以转换为数据类型对象。有关完整说明,请参见数据类型对象 (dtype)。此版本的转换器会将 None 对象转换为NPY_DEFAULT_TYPE 数据类型对象。此函数可与PyArg_ParseTuple 处理中的“O&”字符代码一起使用。

int PyArray_DescrConverter2(PyObject *obj, PyArray_Descr **dtype)#

将任何兼容的 Python 对象 *obj* 转换为 *dtype* 中的数据类型对象。此版本的转换器会转换 None 对象,使返回的数据类型为 NULL。此函数也可与 PyArg_ParseTuple 处理中的“O&”字符一起使用。

int PyArray_DescrAlignConverter(PyObject *obj, PyArray_Descr **dtype)#

类似于PyArray_DescrConverter,但它会像编译器一样将类似 C 结构的对象对齐到字边界。

int PyArray_DescrAlignConverter2(PyObject *obj, PyArray_Descr **dtype)#

类似于PyArray_DescrConverter2,但它会像编译器一样将类似 C 结构的对象对齐到字边界。

数据类型提升和检查#

PyArray_DTypeMeta *PyArray_CommonDType(const PyArray_DTypeMeta *dtype1, const PyArray_DTypeMeta *dtype2)#

此函数定义公共 DType 运算符。请注意,公共 DType 不会是 object(除非其中一个 DType 是 object)。类似于numpy.result_type,但它作用于类而不是实例。

PyArray_DTypeMeta *PyArray_PromoteDTypeSequence(npy_intp length, PyArray_DTypeMeta **dtypes_in)#

以一种即使更改顺序也能保证稳定结果的方式提升 DType 列表。此函数更智能,并且当common_dtype(common_dtype(dt1, dt2), dt3)依赖于操作顺序或失败时,它通常可以返回成功且明确的结果。然而,DType 应该旨在确保它们的公共 dtype 实现是结合性和交换性的!(主要是,无符号整数和有符号整数不是。)

为了保证一致的结果,DType 必须“传递地”实现公共 DType。如果 A 提升 B,而 B 提升 C,那么 A 通常也必须提升 C;其中“提升”意味着实现提升。(抽象 DType 有一些例外)

通常,只要最通用的 dtype 严格大于或与所有其他 dtype 兼容,这种方法总是有效的。例如,将float16与任何其他浮点数、整数或无符号整数提升,都会再次得到一个浮点数。

PyArray_Descr *PyArray_GetDefaultDescr(const PyArray_DTypeMeta *DType)#

给定一个 DType 类,返回默认实例(描述符)。这首先检查singleton,如果必要,只调用default_descr函数。

自定义数据类型#

2.0 版中的新功能。

这些函数允许在 NumPy 之外定义自定义灵活数据类型。有关新 DType 系统的基本原理和设计的更多详细信息,请参见NEP 42。有关许多示例 DType,请参见numpy-user-dtypes 存储库。另请参见PyArray_DTypeMeta 和 PyArrayDTypeMeta_Spec,了解有关PyArray_DTypeMetaPyArrayDTypeMeta_Spec的文档。

int PyArrayInitDTypeMeta_FromSpec(PyArray_DTypeMeta *Dtype, PyArrayDTypeMeta_Spec *spec)#

初始化一个新的 DType。它目前必须是一个静态 Python C 类型,声明为PyArray_DTypeMeta而不是PyTypeObject。此外,它必须是np.dtype的子类,并将它的类型设置为PyArrayDTypeMeta_Type(在调用PyType_Ready之前),它与普通的PyTypeObject相比,具有额外的字段。有关与参数化和非参数化数据类型的用法,请参见numpy-user-dtypes存储库中的示例。

标志#

可以设置为PyArrayDTypeMeta_Spec以初始化 DType 的标志。

NPY_DT_ABSTRACT#

指示 DType 是 DType 层次结构中的抽象“基”DType,不应直接实例化。

NPY_DT_PARAMETRIC#

指示 DType 是参数化的,并且没有唯一的单例实例。

NPY_DT_NUMERIC#

指示 DType 代表数值。

槽 ID 和 API 函数类型定义#

这些 ID 对应于 DType API 中的槽,用于从PyArrayDTypeMeta_Spec结构的slots数组成员的项目中标识每个槽的实现。

NPY_DT_discover_descr_from_pyobject#
typedef PyArray_Descr *(PyArrayDTypeMeta_DiscoverDescrFromPyobject)(PyArray_DTypeMeta *cls, PyObject *obj)#

在DType推断期间使用,用于为给定的PyObject查找正确的DType。必须返回一个合适的描述符实例,用于存储传入的Python对象中的数据。obj 是要检查的Python对象,cls 是要为其创建描述符的DType类。

NPY_DT_default_descr#
typedef PyArray_Descr *(PyArrayDTypeMeta_DefaultDescriptor)(PyArray_DTypeMeta *cls)#

返回DType的默认描述符实例。必须为参数化数据类型定义。非参数化数据类型默认返回单例。

NPY_DT_common_dtype#
typedef PyArray_DTypeMeta *(PyArrayDTypeMeta_CommonDType)(PyArray_DTypeMeta *dtype1, PyArray_DTypeMeta *dtype2)#

给定两个输入DType,确定可以存储两种类型值的适当“公共”DType。如果不存在此类类型,则返回Py_NotImplemented

NPY_DT_common_instance#
typedef PyArray_Descr *(PyArrayDTypeMeta_CommonInstance)(PyArray_Descr *dtype1, PyArray_Descr *dtype2)#

给定两个输入描述符,确定可以存储两个实例值的适当“公共”描述符。错误时返回NULL

NPY_DT_ensure_canonical#
typedef PyArray_Descr *(PyArrayDTypeMeta_EnsureCanonical)(PyArray_Descr *dtype)#

返回描述符实例的“规范”表示。规范描述符的概念概括了字节序的概念,因为规范描述符始终具有本地字节序。如果描述符已经是规范的,则此函数返回对输入描述符的新引用。

NPY_DT_setitem#
typedef int (PyArrayDTypeMeta_SetItem)(PyArray_Descr*, PyObject*, char*)#

实现给定PyObject的数组元素的标量setitem。

NPY_DT_getitem#
typedef PyObject *(PyArrayDTypeMeta_GetItem)(PyArray_Descr*, char*)#

实现数组元素的标量getitem。必须返回一个Python标量。

NPY_DT_get_clear_loop#

如果已定义,则设置一个遍历循环,该循环清除数组中的数据。这对于必须在数组被垃圾回收之前清理数组条目的引用数组最有用。实现PyArrayMethod_GetTraverseLoop

NPY_DT_get_fill_zero_loop#

如果已定义,则设置一个遍历循环,该循环用“零”值填充数组,这可能具有DType特定的含义。这在numpy.zeros内部调用,用于需要写入表示零的自定义哨兵值的数组,如果由于某种原因零填充数组不足够。

NPY_DT_finalize_descr#
typedef PyArray_Descr *(PyArrayDTypeMeta_FinalizeDescriptor)(PyArray_Descr *dtype)#

如果已定义,则在创建数组后调用的函数,用于“完成”描述符实例。此函数的一种用途是强制新创建的数组具有新创建的描述符实例,无论用户提供什么输入描述符。

PyArray_ArrFuncs 插槽#

除了上述插槽外,还公开了以下插槽,以便填充附加到描述符实例的PyArray_ArrFuncs结构。请注意,将来这些将被适当的DType API插槽替换,但目前我们公开了旧版PyArray_ArrFuncs插槽。

NPY_DT_PyArray_ArrFuncs_getitem#

允许设置每个dtype的getitem。请注意,除非使用NPY_DT_getitem ID定义的函数调用的默认版本不合适,否则不需要定义此版本。与使用NPY_DT_getitem相比,此版本的速度略快,但有时需要处理NULL输入数组。

NPY_DT_PyArray_ArrFuncs_setitem#

允许设置每个dtype的setitem。除非默认版本(调用使用NPY_DT_setitem ID定义的函数)由于某种原因不适用,否则无需定义。

NPY_DT_PyArray_ArrFuncs_compare#

计算numpy.sort的比较结果,实现PyArray_CompareFunc

NPY_DT_PyArray_ArrFuncs_argmax#

计算numpy.argmax的argmax,实现PyArray_ArgFunc

NPY_DT_PyArray_ArrFuncs_argmin#

计算numpy.argmin的argmin,实现PyArray_ArgFunc

NPY_DT_PyArray_ArrFuncs_dotfunc#

计算numpy.dot的点积,实现PyArray_DotFunc

NPY_DT_PyArray_ArrFuncs_scanfunc#

numpy.fromfile的格式化输入函数,实现PyArray_ScanFunc

NPY_DT_PyArray_ArrFuncs_fromstr#

numpy.fromstring的字符串解析函数,实现PyArray_FromStrFunc

NPY_DT_PyArray_ArrFuncs_nonzero#

计算numpy.nonzero的非零函数,实现PyArray_NonzeroFunc

NPY_DT_PyArray_ArrFuncs_fill#

numpy.ndarray.fill的数组填充函数,实现PyArray_FillFunc

NPY_DT_PyArray_ArrFuncs_fillwithscalar#

用于numpy.ndarray.fill,用标量值填充数组的函数,实现PyArray_FillWithScalarFunc

NPY_DT_PyArray_ArrFuncs_sort#

长度为NPY_NSORTS的PyArray_SortFunc数组。如果设置,则允许为NumPy实现的每个排序算法定义自定义排序实现。

NPY_DT_PyArray_ArrFuncs_argsort#

长度为NPY_NSORTS的PyArray_ArgSortFunc数组。如果设置,则允许为NumPy实现的每个排序算法定义自定义argsort实现。

宏和静态内联函数#

这些宏和静态内联函数用于在使用PyArray_DTypeMeta实例时编写更易理解和更符合习惯的代码。

NPY_DTYPE(descr)#

返回指向给定描述符实例的DType的PyArray_DTypeMeta *指针。

static inline PyArray_DTypeMeta *NPY_DT_NewRef(PyArray_DTypeMeta *o)#

返回指向DType的新引用的PyArray_DTypeMeta *指针。

转换实用程序#

用于PyArg_ParseTuple#

所有这些函数都可以在PyArg_ParseTuple (…) 中使用“O&”格式说明符,自动将任何Python对象转换为所需的C对象。如果成功,所有这些函数都返回NPY_SUCCEED;否则返回NPY_FAIL。所有这些函数的第一个参数都是一个Python对象。第二个参数是要将Python对象转换到的C类型的**地址**。

警告

请务必了解使用这些转换函数时应采取哪些步骤来管理内存。根据您的使用情况,这些函数可能需要释放内存和/或更改特定对象的引用计数。

int PyArray_Converter(PyObject *obj, PyObject **address)#

将任何Python对象转换为PyArrayObject。如果PyArray_Check (obj) 为TRUE,则其引用计数将递增,并将一个引用放置在address中。如果obj不是数组,则使用PyArray_FromAny将其转换为数组。无论返回什么,当您完成此例程在address中返回的对象时,都必须对其进行DECREF。

int PyArray_OutputConverter(PyObject *obj, PyArrayObject **address)#

这是传递给函数的输出数组的默认转换器。如果objPy_NoneNULL,则*address将为NULL,但调用将成功。如果PyArray_Check ( obj) 为TRUE,则它将在不增加其引用计数的情况下返回到*address

int PyArray_IntpConverter(PyObject *obj, PyArray_Dims *seq)#

将小于NPY_MAXDIMS的任何Python序列obj转换为npy_intp的C数组。Python对象也可以是单个数字。seq变量是指向一个结构体的指针,该结构体具有成员ptr和len。成功返回后,seq ->ptr包含一个指向必须释放的内存的指针,方法是调用PyDimMem_FREE,以避免内存泄漏。对内存大小的限制允许此转换器方便地用于要解释为数组形状的序列。

int PyArray_BufferConverter(PyObject *obj, PyArray_Chunk *buf)#

将任何具有(单段)缓冲区接口的 Python 对象 *obj* 转换为一个变量,该变量的成员详细描述了该对象对其内存块的使用情况。*buf* 变量是指向一个结构体的指针,该结构体具有 base、ptr、len 和 flags 成员。PyArray_Chunk 结构体与 Python 的缓冲区对象二进制兼容(在 32 位平台上通过其 len 成员,在 64 位平台上通过其 ptr 成员)。返回时,base 成员设置为 *obj*(如果 *obj* 已经是指向另一个对象的缓冲区对象,则设置为其 base)。如果您需要保留内存,请务必对 base 成员执行 INCREF 操作。内存块由 *buf* ->ptr 成员指向,长度为 *buf* ->len。如果 *obj* 具有可写缓冲区接口,则 *buf* 的 flags 成员将设置 NPY_ARRAY_ALIGNEDNPY_ARRAY_WRITEABLE 标志。

int PyArray_AxisConverter(PyObject *obj, int *axis)#

将表示轴参数的 Python 对象 *obj* 转换为适合传递给接受整数轴作为参数的函数的正确值。具体来说,如果 *obj* 为 None,则 *axis* 将设置为 NPY_RAVEL_AXIS,C-API 函数在接收轴参数时会正确解释该值。

int PyArray_BoolConverter(PyObject *obj, npy_bool *value)#

将任何 Python 对象 *obj* 转换为 NPY_TRUENPY_FALSE,并将结果放入 *value* 中。

int PyArray_ByteorderConverter(PyObject *obj, char *endian)#

将 Python 字符串转换为相应的字节序字符:'>'、'<'、's'、'=' 或 '|'。

int PyArray_SortkindConverter(PyObject *obj, NPY_SORTKIND *sort)#

将 Python 字符串转换为以下其中之一:NPY_QUICKSORT(以 'q' 或 'Q' 开头)、NPY_HEAPSORT(以 'h' 或 'H' 开头)、NPY_MERGESORT(以 'm' 或 'M' 开头)或 NPY_STABLESORT(以 't' 或 'T' 开头)。NPY_MERGESORTNPY_STABLESORT 为向后兼容而相互别名,并可能根据数据类型引用几种稳定排序算法之一。

int PyArray_SearchsideConverter(PyObject *obj, NPY_SEARCHSIDE *side)#

将 Python 字符串转换为以下其中之一:NPY_SEARCHLEFT(以 'l' 或 'L' 开头)或 NPY_SEARCHRIGHT(以 'r' 或 'R' 开头)。

int PyArray_OrderConverter(PyObject *obj, NPY_ORDER *order)#

将 Python 字符串 'C'、'F'、'A' 和 'K' 转换为 NPY_ORDER 枚举 NPY_CORDERNPY_FORTRANORDERNPY_ANYORDERNPY_KEEPORDER

int PyArray_CastingConverter(PyObject *obj, NPY_CASTING *casting)#

将 Python 字符串 'no'、'equiv'、'safe'、'same_kind' 和 'unsafe' 转换为 NPY_CASTING 枚举 NPY_NO_CASTINGNPY_EQUIV_CASTINGNPY_SAFE_CASTINGNPY_SAME_KIND_CASTINGNPY_UNSAFE_CASTING

int PyArray_ClipmodeConverter(PyObject *object, NPY_CLIPMODE *val)#

将Python字符串“clip”、“wrap”和“raise”转换为NPY_CLIPMODE枚举NPY_CLIPNPY_WRAPNPY_RAISE

int PyArray_ConvertClipmodeSequence(PyObject *object, NPY_CLIPMODE *modes, int n)#

将剪切模式序列或单个剪切模式转换为NPY_CLIPMODE值的C数组。在调用此函数之前,必须知道剪切模式的数量 *n*。提供此函数是为了帮助函数允许每个维度使用不同的剪切模式。

其他转换#

int PyArray_PyIntAsInt(PyObject *op)#

将所有类型的Python对象(包括数组和数组标量)转换为标准整数。发生错误时,返回-1并设置异常。您可能会发现宏很有用

#define error_converting(x) (((x) == -1) && PyErr_Occurred())
npy_intp PyArray_PyIntAsIntp(PyObject *op)#

将所有类型的Python对象(包括数组和数组标量)转换为(平台指针大小的)整数。发生错误时,返回-1并设置异常。

int PyArray_IntpFromSequence(PyObject *seq, npy_intp *vals, int maxvals)#

将作为 *seq* 传入的任何 Python 序列(或单个 Python 数字)转换为(最多)*maxvals* 个指针大小的整数,并将它们放置在 *vals* 数组中。序列可以小于 *maxvals*,因为返回转换对象的个数。

包含和导入 C API#

要使用 NumPy C-API,您通常需要包含 numpy/ndarrayobject.h 头文件,以及一些与 ufunc 相关的功能的 numpy/ufuncobject.harrayobject.hndarrayobject.h 的别名)。

这两个头文件导出了大多数相关的功能。一般来说,任何使用 NumPy API 的项目都必须使用 PyArray_ImportNumPyAPI()import_array() 函数之一导入 NumPy。在某些情况下,不需要需要 import_array() 的功能,因为您只需要类型定义。在这种情况下,包含 numpy/ndarratypes.h 就足够了。

对于典型的 Python 项目,多个 C 或 C++ 文件将编译成单个共享对象(Python C 模块),并且应该在其模块初始化中调用 PyArray_ImportNumPyAPI()

当您只有一个 C 文件时,这将包括

#include "numpy/ndarrayobject.h"

PyMODINIT_FUNC PyInit_my_module(void)
{
    if (PyArray_ImportNumPyAPI() < 0) {
        return NULL;
    }
    /* Other initialization code. */
}

但是,大多数项目将有其他 C 文件,所有这些文件都链接到单个 Python 模块中。在这种情况下,辅助 C 文件通常没有规范的位置来调用 PyArray_ImportNumPyAPI(尽管经常调用它是可以的并且很快)。

为了解决这个问题,NumPy 提供了以下模式,即修改主文件以在包含之前定义 PY_ARRAY_UNIQUE_SYMBOL

/* Main module file */
#define PY_ARRAY_UNIQUE_SYMBOL MyModule
#include "numpy/ndarrayobject.h"

PyMODINIT_FUNC PyInit_my_module(void)
{
    if (PyArray_ImportNumPyAPI() < 0) {
        return NULL;
    }
    /* Other initialization code. */
}

而其他文件使用

/* Second file without any import */
#define NO_IMPORT_ARRAY
#define PY_ARRAY_UNIQUE_SYMBOL MyModule
#include "numpy/ndarrayobject.h"

当然,您可以将定义添加到整个项目中使用的本地头文件中。您只需要确保主文件_不_定义 NO_IMPORT_ARRAY

对于 numpy/ufuncobject.h,相同的逻辑适用,但唯一的符号机制是 #define PY_UFUNC_UNIQUE_SYMBOL(两者可以匹配)。

此外,您可能希望添加 #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION 以避免有关可能使用旧 API 的警告。

注意

如果您遇到访问冲突,请确保正确导入了 NumPy API 并且符号 PyArray_API 不为 NULL。在调试器中,此符号的实际名称将是 PY_ARRAY_UNIQUE_SYMBOL``+``PyArray_API,例如上面的 MyModulePyArray_API。(例如,即使是崩溃之前的 printf("%p\n", PyArray_API);)。

机制细节和动态链接#

该机制的主要部分是,如果没有 NumPy 需要为您定义一个 void **PyArray_API 表来查找所有函数。根据您的宏设置,这将采用不同的路径,具体取决于是否定义了NO_IMPORT_ARRAYPY_ARRAY_UNIQUE_SYMBOL

  • 如果两者都没有定义,则 C-API 被声明为 static void **PyArray_API,因此它仅在使用 #include <numpy/arrayobject.h> 的编译单元/文件中可见。

  • 如果仅定义了 PY_ARRAY_UNIQUE_SYMBOL(它可以为空),则将其声明为非静态 void **,允许其他链接的文件使用它。

  • 如果定义了 NO_IMPORT_ARRAY,则该表被声明为 extern void **,这意味着它必须链接到不使用 NO_IMPORT_ARRAY 的文件。

PY_ARRAY_UNIQUE_SYMBOL 机制还对名称进行混淆以避免冲突。

NumPy 版本更改: 2.1 更改了头文件以避免在单个共享对象/dll 之外共享表(在 Windows 上始终如此)。有关详细信息,请参阅NPY_API_SYMBOL_ATTRIBUTE

为了从另一个扩展模块使用 C-API,必须调用import_array函数。如果扩展模块在一个 .c 文件中自包含,那么这就是需要做的全部工作。但是,如果扩展模块涉及需要 C-API 的多个文件,则必须采取一些额外的步骤。

int PyArray_ImportNumPyAPI(void)#

确保导入了 NumPy C-API 并可以使用。成功时返回 0,如果无法导入 NumPy,则返回 -1 并设置错误。虽然最好在模块初始化时调用它一次,但如果多次调用此函数,它非常轻量级。

2.0 版中的新增功能: 此函数在 npy_2_compat.h 头文件中进行了反向移植。

import_array(void)#

此函数必须在将使用 C-API 的模块的初始化部分调用。它导入存储函数指针表的模块,并将正确的变量指向它。此宏在出错时包含 return NULL;,因此 PyArray_ImportNumPyAPI() 更适合于自定义错误检查。您也可能会看到 _import_array()(一个函数,而不是宏,但如果失败,您可能需要引发更好的错误)以及变体 import_array1(ret) 的使用,后者自定义返回值。

PY_ARRAY_UNIQUE_SYMBOL#
NPY_API_SYMBOL_ATTRIBUTE#

2.1 版本的新增功能。

另一个符号,可用于共享例如超出共享对象边界的可见性。默认情况下,NumPy 添加 C 可见性隐藏属性(如果可用):void __attribute__((visibility("hidden"))) **PyArray_API;。您可以通过定义 NPY_API_SYMBOL_ATTRIBUTE 来更改此属性,这将使其变为:void NPY_API_SYMBOL_ATTRIBUTE **PyArray_API;(通过唯一符号进行附加的名称修改)。

添加一个空的 #define NPY_API_SYMBOL_ATTRIBUTE 将与 NumPy 1.x 的行为相同。

注意

Windows 从未有过共享可见性,尽管您可以使用此宏来实现它。我们通常不建议跨越共享边界进行共享,因为导入数组 API 包括 NumPy 版本检查。

NO_IMPORT_ARRAY#

ndarrayobject.h 包含语句之前定义 NO_IMPORT_ARRAY 表示 NumPy C API 导入在不同的文件中处理,并且此处不会添加包含机制。您必须有一个未定义 NO_IMPORT_ARRAY 的文件。

#define PY_ARRAY_UNIQUE_SYMBOL cool_ARRAY_API
#include <numpy/arrayobject.h>

另一方面,coolhelper.c 将在顶部包含:

#define NO_IMPORT_ARRAY
#define PY_ARRAY_UNIQUE_SYMBOL cool_ARRAY_API
#include <numpy/arrayobject.h>

只要确保在包含该文件之前定义了 NO_IMPORT_ARRAY,您也可以将最后两行常见的代码放入扩展本地头文件中。

在内部,这些 #define 的工作方式如下:

  • 如果两者都没有定义,则 C-API 被声明为 static void**,因此它仅对包含 numpy/arrayobject.h 的编译单元可见。

  • 如果定义了 PY_ARRAY_UNIQUE_SYMBOL,但未定义 NO_IMPORT_ARRAY,则 C-API 被声明为 void**,因此它也对其他编译单元可见。

  • 如果定义了 NO_IMPORT_ARRAY,无论是否定义了 PY_ARRAY_UNIQUE_SYMBOL,C-API 都被声明为 extern void**,因此预计它将在另一个编译单元中定义。

  • 每当定义 PY_ARRAY_UNIQUE_SYMBOL 时,它还会更改保存 C-API 的变量的名称(默认为 PyArray_API)为宏定义的任何名称。

检查 API 版本#

因为 Python 扩展在大多数平台上的使用方法与常用库不同,所以某些错误无法在构建时甚至运行时自动检测到。例如,如果您使用仅适用于 numpy >= 1.3.0 的函数构建扩展,并在稍后使用 numpy 1.2 导入扩展,则不会收到导入错误(但调用函数时几乎肯定会出现段错误)。这就是提供多个函数来检查 numpy 版本的原因。宏 NPY_VERSIONNPY_FEATURE_VERSION 对应于用于构建扩展的 numpy 版本,而函数 PyArray_GetNDArrayCVersionPyArray_GetNDArrayCFeatureVersion 返回的版本对应于运行时 numpy 的版本。

ABI 和 API 兼容性规则可以总结如下:

  • 每当 NPY_VERSION != PyArray_GetNDArrayCVersion() 时,都必须重新编译扩展(ABI 不兼容)。

  • NPY_VERSION == PyArray_GetNDArrayCVersion()NPY_FEATURE_VERSION <= PyArray_GetNDArrayCFeatureVersion() 表示向后兼容的更改。

在每个 numpy 版本中都会自动检测 ABI 不兼容性。API 不兼容性检测已在 numpy 1.4.0 中添加。如果您想使用一个扩展二进制文件支持许多不同的 numpy 版本,则必须使用尽可能低的 NPY_FEATURE_VERSION 来构建您的扩展。

NPY_VERSION#

ndarray 对象的当前版本(检查此变量是否已定义以保证正在使用 numpy/arrayobject.h 头文件)。

NPY_FEATURE_VERSION#

C-API 的当前版本。

unsigned int PyArray_GetNDArrayCVersion(void)#

这仅返回 NPY_VERSION 的值。NPY_VERSION 在 ABI 级别的向后不兼容更改时发生变化。但是,因为它在 C-API 中,所以比较此函数的输出与当前头文件中定义的值提供了一种测试 C-API 是否已更改的方法,从而需要重新编译使用 C-API 的扩展模块。这在函数 import_array 中会自动检查。

unsigned int PyArray_GetNDArrayCFeatureVersion(void)#

这仅返回 NPY_FEATURE_VERSION 的值。NPY_FEATURE_VERSION 在 API 更改时发生变化(例如,添加函数)。更改的值并不总是需要重新编译。

内存管理#

char *PyDataMem_NEW(size_t nbytes)#
void PyDataMem_FREE(char *ptr)#
char *PyDataMem_RENEW(void *ptr, size_t newbytes)#

分配、释放和重新分配内存的函数。除非被覆盖,否则这些函数用于内部管理数组数据内存。

npy_intp *PyDimMem_NEW(int nd)#
void PyDimMem_FREE(char *ptr)#
npy_intp *PyDimMem_RENEW(void *ptr, size_t newnd)#

分配、释放和重新分配维度和步幅内存的宏。

void *PyArray_malloc(size_t nbytes)#
void PyArray_free(void *ptr)#
void *PyArray_realloc(npy_intp *ptr, size_t nbytes)#

这些宏使用不同的内存分配器,具体取决于常量 NPY_USE_PYMEM。当 NPY_USE_PYMEM 为 0 时,使用系统 malloc;如果 NPY_USE_PYMEM 为 1,则使用 Python 内存分配器。

NPY_USE_PYMEM#
int PyArray_ResolveWritebackIfCopy(PyArrayObject *obj)#

如果 obj->flags 包含 NPY_ARRAY_WRITEBACKIFCOPY,此函数将清除标志,DECREF obj->base 并使其可写,并将 obj->base 设置为 NULL。然后它将 obj->data 复制到 obj->base->data,并返回复制操作的错误状态。这与 PyArray_SetWritebackIfCopyBase 相反。通常,在完成 obj 后,就在 Py_DECREF(obj) 之前调用它。可以多次调用它,也可以使用 NULL 输入。另请参见 PyArray_DiscardWritebackIfCopy

如果没有任何操作,则返回 0;如果出错,则返回 -1;如果采取了行动,则返回 1。

线程支持#

只有在扩展模块编译期间 NPY_ALLOW_THREADS 评估为 True 时,这些宏才具有意义。否则,这些宏等效于空格。Python 为每个 Python 进程使用单个全局解释器锁 (GIL),以便一次只能执行一个线程(即使在多 CPU 机器上也是如此)。当调用可能需要一些时间才能计算(并且对其他线程没有副作用,例如更新的全局变量)的编译函数时,应释放 GIL,以便在进行耗时计算时可以运行其他 Python 线程。这可以使用两组宏来实现。通常,如果代码块中使用了一组中的一个宏,则必须在同一代码块中使用所有这些宏。NPY_ALLOW_THREADS 为真(定义为 1),除非构建选项 -Ddisable-threading 设置为 true,在这种情况下,NPY_ALLOW_THREADS 为假 (0)。

NPY_ALLOW_THREADS#

组 1#

此组用于调用可能需要一些时间但未使用任何 Python C-API 调用的代码。因此,应在其计算期间释放 GIL。

NPY_BEGIN_ALLOW_THREADS#

等效于 Py_BEGIN_ALLOW_THREADS,但它使用 NPY_ALLOW_THREADS 来确定宏是否被替换为空格。

NPY_END_ALLOW_THREADS#

等效于 Py_END_ALLOW_THREADS,但它使用 NPY_ALLOW_THREADS 来确定宏是否被替换为空格。

NPY_BEGIN_THREADS_DEF#

放在变量声明区域。此宏设置用于存储 Python 状态的必要变量。

NPY_BEGIN_THREADS#

放在不需要 Python 解释器(没有 Python C-API 调用)的代码之前。此宏保存 Python 状态并释放 GIL。

NPY_END_THREADS#

放在不需要 Python 解释器的代码之后。此宏获取 GIL 并从保存的变量中恢复 Python 状态。

void NPY_BEGIN_THREADS_DESCR(PyArray_Descr *dtype)#

仅当 *dtype* 不包含在循环执行期间可能需要 Python 解释器的任意 Python 对象时,才释放 GIL。

void NPY_END_THREADS_DESCR(PyArray_Descr *dtype)#

在使用此宏的 BEGIN 形式释放 GIL 的情况下,重新获取 GIL。

void NPY_BEGIN_THREADS_THRESHOLDED(int loop_size)#

仅当 *loop_size* 超过最小阈值(当前设置为 500)时,才释放 GIL。应与 NPY_END_THREADS 匹配以重新获取 GIL。

组 2#

此组用于在释放 GIL 后重新获取 Python GIL。例如,假设 GIL 已被释放(使用之前的调用),然后代码中的某些路径(可能在不同的子例程中)需要使用 Python C-API,则这些宏对于获取 GIL 非常有用。这些宏实质上完成了前三个宏的逆向操作(获取锁并保存其状态),然后使用保存的状态重新释放它。

NPY_ALLOW_C_API_DEF#

放在变量声明区域以设置必要的变量。

NPY_ALLOW_C_API#

放在需要调用 Python C-API 的代码之前(当已知 GIL 已经被释放时)。

NPY_DISABLE_C_API#

放在需要调用 Python C-API 的代码之后(以重新释放 GIL)。

提示

线程支持宏之后切勿使用分号。

优先级#

NPY_PRIORITY#

数组的默认优先级。

NPY_SUBTYPE_PRIORITY#

默认子类型优先级。

NPY_SCALAR_PRIORITY#

默认标量优先级(非常小)

double PyArray_GetPriority(PyObject *obj, double def)#

返回 __array_priority__ 属性(转换为双精度浮点数)的 *obj*,如果不存在该名称的属性,则返回 *def*。为 PyArray_Type 类型的对象提供了避免属性查找的快速返回。

默认缓冲区#

NPY_BUFSIZE#

用户可设置的内部缓冲区的默认大小。

NPY_MIN_BUFSIZE#

用户可设置的内部缓冲区的最小大小。

NPY_MAX_BUFSIZE#

用户可设置缓冲区的最大允许大小。

其他常量#

NPY_NUM_FLOATTYPE#

浮点类型的数量。

NPY_MAXDIMS#

NumPy 允许使用的最大维度数。在 NumPy 2 之前,此值设置为 32,现在设置为 64。

注意

我们建议您避免使用NPY_MAXDIMS。NumPy 的未来版本可能会取消任何维度限制(以及该常量)。创建此限制是为了使 NumPy 能够内部使用栈分配作为临时空间。

如果您的算法具有合理的最大维度数,您可以检查并将其用于局部。

NPY_MAXARGS#

某些函数中可使用的最大数组参数数量。在 NumPy 2 之前,此值是 32,现在是 64。为了继续允许将其用作检查参数数量是否与 ufunc 兼容的检查,此宏现在依赖于运行时。

注意

我们不建议使用NPY_MAXARGS,除非明确与检查已知的 NumPy 限制相关。

NPY_FALSE#

定义为 0,用于布尔值。

NPY_TRUE#

定义为 1,用于布尔值。

NPY_FAIL#

失败的转换函数的返回值,这些函数使用 PyArg_ParseTuple 之类的函数中的“O&”语法调用。

NPY_SUCCEED#

成功转换函数的返回值,这些函数使用 PyArg_ParseTuple 之类的函数中的“O&”语法调用。

NPY_RAVEL_AXIS#

一些 NumPy 函数(主要是 Python 函数的 C 入口点)具有 axis 参数。此宏可用于 axis=None

注意

此宏在运行时依赖于 NumPy 版本。当前值为最小整数。但是,在 NumPy 1.x 中使用了 NPY_MAXDIMS(当时设置为 32)。

杂项宏#

int PyArray_SAMESHAPE(PyArrayObject *a1, PyArrayObject *a2)#

如果数组a1a2具有相同的形状,则评估结果为 True。

PyArray_MAX(a, b)#

返回ab中的最大值。如果(a)或(b)是表达式,则它们将被评估两次。

PyArray_MIN(a, b)#

返回ab中的最小值。如果(a)或(b)是表达式,则它们将被评估两次。

void PyArray_DiscardWritebackIfCopy(PyArrayObject *obj)#

如果obj->flags具有NPY_ARRAY_WRITEBACKIFCOPY,则此函数清除标志,DECREF obj->base 并使其可写,并将obj->base设置为 NULL。与PyArray_ResolveWritebackIfCopy相比,它不会尝试从obj->base复制数据。这将撤消PyArray_SetWritebackIfCopyBase。通常,在发生错误并且您完成对obj的操作后,就在Py_DECREF(obj)之前调用此函数。可以多次调用它,也可以使用NULL输入调用它。

枚举类型#

enum NPY_SORTKIND#

一种特殊的变量类型,可以取不同的值以指示正在使用的排序算法。

enumerator NPY_QUICKSORT#
enumerator NPY_HEAPSORT#
enumerator NPY_MERGESORT#
enumerator NPY_STABLESORT#

用作NPY_MERGESORT的别名,反之亦然。

enumerator NPY_NSORTS#

定义为排序的数量。由于需要向后兼容性,它固定为三个,因此NPY_MERGESORTNPY_STABLESORT相互作为别名,并且可能根据数据类型引用几种稳定的排序算法之一。

enum NPY_SCALARKIND#

一种特殊的变量类型,指示在确定标量强制规则时区分的标量“种类”的数量。此变量可以取以下值:

enumerator NPY_NOSCALAR#
enumerator NPY_BOOL_SCALAR#
enumerator NPY_INTPOS_SCALAR#
enumerator NPY_INTNEG_SCALAR#
enumerator NPY_FLOAT_SCALAR#
enumerator NPY_COMPLEX_SCALAR#
enumerator NPY_OBJECT_SCALAR#
enumerator NPY_NSCALARKINDS#

定义为标量种类数量(不包括NPY_NOSCALAR)。

enum NPY_ORDER#

一个枚举类型,指示应该以何种元素顺序解释数组。当创建一个全新的数组时,通常只使用**NPY_CORDER**和**NPY_FORTRANORDER**,而当提供一个或多个输入时,顺序可以基于它们。

enumerator NPY_ANYORDER#

如果所有输入都是 Fortran 顺序,则为 Fortran 顺序;否则为 C 顺序。

enumerator NPY_CORDER#

C 顺序。

枚举器 NPY_FORTRANORDER#

Fortran 顺序。

枚举器 NPY_KEEPORDER#

尽可能接近输入顺序的顺序,即使输入既不是 C 顺序也不是 Fortran 顺序。

枚举 NPY_CLIPMODE#

一个变量类型,指示某些函数中应应用的裁剪类型。

枚举器 NPY_RAISE#

大多数操作的默认值,如果索引超出范围,则引发异常。

枚举器 NPY_CLIP#

如果索引超出范围,则将其裁剪到有效范围。

枚举器 NPY_WRAP#

如果索引超出范围,则将其环绕到有效范围。

枚举 NPY_SEARCHSIDE#

一个变量类型,指示返回的索引应该是第一个合适位置的索引(如果为NPY_SEARCHLEFT)还是最后一个(如果为NPY_SEARCHRIGHT)。

枚举器 NPY_SEARCHLEFT#
枚举器 NPY_SEARCHRIGHT#
枚举 NPY_SELECTKIND#

一个变量类型,指示正在使用的选择算法。

枚举器 NPY_INTROSELECT#
枚举 NPY_CASTING#

一个枚举类型,指示数据转换应该有多宽松。这由 NumPy 1.6 中添加的迭代器使用,并打算在将来的版本中更广泛地使用。

枚举器 NPY_NO_CASTING#

只允许相同类型。

枚举器 NPY_EQUIV_CASTING#

允许相同类型和涉及字节交换的转换。

枚举器 NPY_SAFE_CASTING#

只允许不会导致值被舍入、截断或以其他方式更改的转换。

枚举器 NPY_SAME_KIND_CASTING#

允许任何安全转换,以及相同类型的类型之间的转换。例如,使用此规则允许 float64 -> float32。

枚举器 NPY_UNSAFE_CASTING#

允许任何转换,无论可能发生哪种数据丢失。