数组 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)#

版本 1.7 中的新功能。

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

void PyArray_CLEARFLAGS(PyArrayObject *arr, int flags)#

版本 1.7 中的新功能。

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

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

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

npy_intp *PyArray_DIMS(PyArrayObject *arr)#

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

npy_intp *PyArray_SHAPE(PyArrayObject *arr)#

版本 1.7 中的新功能。

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

npy_intp *PyArray_STRIDES(PyArrayObject *arr)#

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

npy_intp PyArray_DIM(PyArrayObject *arr, int n)#

返回第 n \(^{\textrm{th}}\) 维的形状。

npy_intp PyArray_STRIDE(PyArrayObject *arr, int n)#

返回第 n \(^{\textrm{th}}\) 维的步长。

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_SIZEobj)更安全的版本。

npy_intp PyArray_NBYTES(PyArrayObject *arr)#

返回数组消耗的总字节数。

PyObject *PyArray_BASE(PyArrayObject *arr)#

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

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

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

PyArray_Descr *PyArray_DESCR(PyArrayObject *arr)#

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

PyArray_Descr *PyArray_DTYPE(PyArrayObject *arr)#

版本 1.7 中的新功能。

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

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

从ndarray的arr中获取内置类型的Python对象,该对象位于itemptr指向的位置。失败时返回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中给定坐标处的元素,该元素必须分别具有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非NULL,则还可以提供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)#

版本1.6中的新功能。

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

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

如果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,则用 0 对象填充)。

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)#

构造一个新的 1 维数组,其数据类型为 typenum,该数组从 startstop(不包括)以 step 的增量进行范围。等效于 arange (start, stop, step, dtype)。

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

构造一个新的 1 维数组,其数据类型由 descr 确定,该数组从 startstop(不包括)以 step 的增量进行范围。等效于 arange( start, stop, step, typenum )。

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

版本 1.7 中的新功能。

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

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

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

如果提供的对象是数组,则此函数遍历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填充)。新数组将具有NPY_ARRAY_DEFAULT作为其flags成员。context参数未使用。

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)#

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

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 样式)连续且行为良好的函数数组,该对象op的类型(非灵活类型)由枚举的typenum给出,最小深度为min_depth,最大深度为max_depth。等效于对PyArray_FromAny的调用,其中要求设置为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的调用,要求为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,并将要求设置为 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)#

从导出(单段)缓冲区协议的对象 buf(或具有返回导出缓冲区协议的对象的属性 __buffer__)中构造一个单类型的一维 ndarray。将首先尝试可写缓冲区,然后尝试只读缓冲区。返回数组的 NPY_ARRAY_WRITEABLE 标志将反映哪个缓冲区成功。假定数据从对象内存位置的起始位置偏移 offset 个字节开始。缓冲区中数据的类型将根据数据类型描述符 dtype 进行解释。如果 count 为负,则将根据缓冲区的大小和请求的项目大小确定它,否则,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。参数可以是任何嵌套序列或导出数组接口的对象。这是使用 NULL、0、0、0 作为其他参数的 PyArray_FromAny 的宏形式。您的代码必须能够处理任何数据类型描述符和任何数据标志组合才能使用此宏。

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,允许同时提供 typenumflags 参数。

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 是一个转换后的整数(以便 >=MAXDIMS 为 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 元数据字段确实提供了对日期时间/时间增量时间单位信息的访问。

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#

基本类型的 data-type-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 上调用。附加到数组的类型将始终具有大小,因此此宏的数组形式不存在。

版本 1.18 中更改。

对于没有字段的结构化数据类型,此函数现在返回 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)#

版本1.6中的新功能。

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

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

版本1.6中的新功能。

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

这几乎与PyArray_CanCastTypeTo(PyArray_MinScalarType(arr), totype, casting)的结果相同,但它还处理了一个特殊情况,因为对于具有相同位数的类型,无符号整数值集不是整数集的子集。

PyArray_Descr *PyArray_MinScalarType(PyArrayObject *arr)#

版本1.6中的新功能。

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

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

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

版本1.6中的新功能。

查找可以安全地将type1type2转换为其最小大小和类型的的数据类型。此函数是对称且关联的。字符串或 Unicode 结果将是适当的大小,用于存储转换为字符串或 Unicode 的输入类型的最大值。

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

版本1.6中的新功能。

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

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

int PyArray_ObjectType(PyObject *op, int mintype)#

此函数已被PyArray_MinScalarType和/或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中返回,PyArrayObject指针的n长度数组是返回值(如果发生错误,则为NULL)。返回的数组必须由此例程的调用者释放(使用PyDataMem_FREE),并且其中的所有数组对象都必须DECREF,否则会发生内存泄漏。下面的示例模板代码显示了典型用法

在版本 1.18.0 中更改: 标量和零维数组的混合现在生成能够保存标量值的类型。以前,优先考虑数组的 dtype。

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被认为是旧的,新的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)#

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

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

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

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

数组标志#

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

有 6 个(二进制)标志描述数据缓冲区使用的内存区域。这些常量在arrayobject.h 中定义,并确定标志的位位置。Python 公开了简洁的基于属性的接口以及类似字典的接口,用于获取(以及在适当情况下设置)这些标志。

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

在 NumPy 1.6 及更早版本中,以下标志没有 _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 个标志的定义方式是,新创建的行为良好的数组将这些标志定义为真。

NPY_ARRAY_WRITEBACKIFCOPY#

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

这是一个特殊标志,如果此数组表示一个副本(因为用户在PyArray_FromAny 中需要某些标志,并且必须创建其他数组的副本(并且用户要求在此情况下设置此标志)),则会设置此标志。然后,base 属性指向“行为不良”的数组(设置为只读)。PyArray_ResolveWritebackIfCopy 会将其内容复制回“行为不良”的数组(如果需要则进行转换),并将“行为不良”的数组重置为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_ISBEHAVEDarr)为真,则评估为真。

int PyArray_ISFARRAY(PyObject *arr)#

如果 arr 的数据区域是 Fortran 样式连续的,并且 PyArray_ISBEHAVEDarr)为真,则评估为真。

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

插槽和类型定义#

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

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 指示约简是否为空。当它为空时,返回值可能不同。在这种情况下,它是一个“默认”值,可能与通常使用的“标识”值不同。例如

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

  • 我们对对象不使用标识,但对于空的 sum([], dtype=object)prod([], dtype=object) 返回默认值 01。这允许 np.sum(np.array(["a", "b"], dtype=object)) 工作。

  • -infINT_MIN 用于 max 是一个标识,但至少 INT_MIN 不是没有项目时的良好默认值

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

标志#

enum NPY_ARRAYMETHOD_FLAGS#

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

enumerator NPY_METH_REQUIRES_PYAPI#

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

enumerator NPY_METH_NO_FLOATINGPOINT_ERRORS#

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

enumerator NPY_METH_SUPPORTS_UNALIGNED#

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

enumerator NPY_METH_IS_REORDERABLE#

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

enumerator 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 是数组缓冲区的一维大小,stride 是步长,auxdata 是循环的可选额外数据。

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

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)#

特定于数据类型遍历的简化 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)#

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

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

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

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 必须受支持(用于输出参数),并且通常应转发。

此函数的输出将用于构造参数的视图,就像它们是转换后的数据类型一样,并且不使用强制转换。这意味着此机制主要适用于“包装”另一个数据类型实现的数据类型。例如,单位数据类型可以使用它来包装现有的浮点数据类型,而无需重新实现低级 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加上新数组类型的itemsize必须小于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非零,则在原地进行字节交换并返回对self的引用。否则,创建一个字节交换的副本,并保持self不变。

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 print语句格式字符串。

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

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

PyObject *PyArray_Dumps(PyObject *self, int protocol)#

self中的对象pickle到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.reshapeselfshape),其中shape是一个序列。将shape转换为PyArray_Dims结构,并在内部调用PyArray_Newshape。为了向后兼容 - 不推荐使用

PyObject *PyArray_Squeeze(PyArrayObject *self)#

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

警告

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

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

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

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

等效于ndarray.resizeselfnewshape,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.transposeselfpermute)。根据数据结构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.flattenselforder)。返回数组的一维副本。如果orderNPY_FORTRANORDER,则元素将按 Fortran 顺序扫描(第一维变化最快)。如果orderNPY_CORDER,则self的元素将按 C 顺序扫描(最后一维变化最快)。如果order NPY_ANYORDER,则使用PyArray_ISFORTRANself)的结果来确定要展平的顺序。

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

等效于self.ravel(order)。与PyArray_Flattenselforder)具有相同的基本功能,除了如果order为 0 且self为 C 样式连续,则形状将更改,但不会执行复制。

项目选择和操作#

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

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

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

等效于self.put(valuesindicesclipmode)。将values放入self中对应的(展平的)indices处。如果values太小,它将根据需要重复。

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

values中的值放置到self中,只要mask中对应的位置(使用扁平化的上下文)为真。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)。返回一个数组,其中self的项沿axis排序。该数组使用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是一个升序的1维数组,则输出是一个与values形状相同的索引数组,使得如果将values中的元素插入到索引之前,self的顺序将被保留。不会检查self是否为升序。

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

sorter参数,如果非NULL,必须是一个与self长度相同的整数索引的1D数组,它将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 )。返回由axis1axis2定义的二维数组的offset对角线。

npy_intp PyArray_CountNonzero(PyArrayObject *self)#

版本1.6中的新功能。

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

PyObject *PyArray_Nonzero(PyArrayObject *self)#

等价于 ndarray.nonzero (self)。返回一个元组,其中包含用于选择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,则调用者有责任对out执行 Py_DECREF 操作,否则会发生内存泄漏。

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

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

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

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

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

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

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

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

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

返回self沿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 的元素的 1 维向量和。在将数据转换为数据类型 rtype 后执行求和。

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

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

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

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

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

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

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

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

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

等价于 ndarray.any (self, axis)。返回一个数组,对于由 axis 定义的 self 的每个 1 维子数组,如果任何元素都为 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 样式数组,用于 1 维、2 维和 3 维的 ndarray。

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

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

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

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

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

注意

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

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

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

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

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

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

计算 obj1obj2 的最后几个维度上的积和。这两个数组都不进行共轭。

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

计算 obj1 的最后一个维度和 obj2 的倒数第二个维度上的积和。对于 2 维数组,这表示矩阵积。这两个数组都不进行共轭。

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

版本1.6中的新功能。

与 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)#

版本1.6中的新功能。

将爱因斯坦求和约定应用于提供的数组操作数,返回一个新数组或将结果放入 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 是可用内存段的假定大小。如果 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。

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

版本 1.7.0 中的新增功能。

type NpyAuxData#

在处理由其他数据类型组成的更复杂的数据类型(例如结构体数据类型)时,创建操作数据类型的内部循环需要携带其他数据。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 的释放函数,如果 auxdata 为 NULL 则不执行任何操作。

NpyAuxData *NPY_AUXDATA_CLONE(NpyAuxData *auxdata)#

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

数组迭代器#

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

数组迭代器是一种简单的方法,可以快速有效地访问 N 维数组的元素,如 示例 中所示,该示例提供了更多关于从 C 遍历数组的这种有用方法的描述。

PyObject *PyArray_IterNew(PyObject *arr)#

从数组 arr 返回数组迭代器对象。这等效于 arr. flat。数组迭代器对象使在 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)#

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

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个迭代器的data-pointer。

void PyArray_MultiIter_NEXTi(PyObject *multi, int i)#

仅推进第i个迭代器的指针。

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 的例程,这些例程可以正确地广播其输入,然后将例程的带步长的 1 维版本作为内循环调用。此 1 维版本通常针对速度进行了优化,因此循环应在不需要大步长跳跃的轴上执行。

邻域迭代器#

版本 1.4.0 中的新功能。

邻域迭代器是迭代器对象的子类,可用于迭代某个点的邻域。例如,您可能希望迭代 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[-2] 将为 1,x[4] 将为 4,x[5] 将为 1,等等。

NPY_NEIGHBORHOOD_ITER_CIRCULAR_PADDING#

循环填充。边界外的值将如同数组被重复一样。例如,对于数组 [1, 2, 3, 4],x[-2] 将为 3,x[-2] 将为 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 的数组标量对象。预计 base 是数据所有者的数组对象。如果dtypevoid 标量,或者如果设置了NPY_USE_GETITEM 标志并且已知getitem 方法在不检查arr 是否为NULL 的情况下使用了arr 参数,则需要 base。否则base 可以为NULL

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

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

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

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

根据 outcodescalar(应为数组标量对象)返回 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 1.6.0 中引入的替代机制的函数 PyArray_MinScalarType

返回由typenum表示的标量类型以及*arr中的数组(如果arr不为NULL)。假设该数组为秩0,并且仅当typenum表示有符号整数时才使用。如果arr不为NULL且第一个元素为负数,则返回NPY_INTNEG_SCALAR,否则返回NPY_INTPOS_SCALAR。可能的返回值是NPY_SCALARKIND中枚举的值。

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

有关NumPy类型提升的详细信息,请参阅函数PyArray_ResultType,该函数在NumPy 1.6.0中进行了更新。

实现标量强制转换规则。只有当此函数返回非零值时,才会将标量从thistype静默强制转换为neededtype。如果scalar为NPY_NOSCALAR,则此函数等效于PyArray_CanCastSafely。规则是,相同KIND的标量可以强制转换为相同KIND的数组。此规则意味着高精度标量永远不会导致相同KIND的低精度数组进行向上转换。

数据类型描述符#

警告

数据类型对象必须进行引用计数,因此请注意不同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,则所有字节序都会交换。其他有效的新endian值是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对象可以转换为数据类型对象。有关完整说明,请参阅Data type objects (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 应该旨在确保其 common-dtype 实现是结合性和交换性的!(主要是,无符号整数和有符号整数不是。)

为了保证一致的结果,DType 必须“传递地”实现 common-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 内部调用,用于需要写入表示零的自定义哨兵值的数组,如果由于某种原因零填充数组不足够的话。实现 PyArrayMethod_GetTraverseLoop

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#

允许设置每个数据类型的获取项。请注意,除非使用 NPY_DT_getitem ID 定义的函数调用的默认版本不合适,否则无需定义此版本。此版本将比使用 NPY_DT_getitem 略快,但有时需要处理 NULL 输入数组的代价。

NPY_DT_PyArray_ArrFuncs_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_ALIGNED 以及 NPY_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 头文件,以及 numpy/ufuncobject.h 以获得一些与 ufunc 相关的功能(arrayobject.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 已被 #define,但 NO_IMPORT_ARRAY 未被 #define,则 C-API 被声明为 void**,以便它也对其他编译单元可见。

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

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

检查 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() 表示向后兼容的更改。

ABI 不兼容性在每个 numpy 版本中都会自动检测到。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_VERSIONNPY_VERSION 在 ABI 级别发生向后不兼容更改时发生变化。但是,因为它在 C-API 中,所以比较此函数的输出与当前头文件中定义的值提供了一种方法来测试 C-API 是否已更改,从而需要重新编译使用 C-API 的扩展模块。这在函数 import_array 中会自动检查。

unsigned int PyArray_GetNDArrayCFeatureVersion(void)#

版本 1.4.0 中的新功能。

这仅返回值 NPY_FEATURE_VERSIONNPY_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,则此函数清除标志,对obj->base执行DECREF操作并使其可写,并将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很有用。这些宏基本上完成了前三个宏的反向操作(获取LOCK并保存其状态),然后使用保存的状态重新释放它。

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)#

返回obj__array_priority__属性(转换为double),如果不存在该名称的属性,则返回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兼容的检查,此宏现在依赖于运行时。

注意

我们不鼓励任何不与检查已知的NumPy限制明确相关的NPY_MAXARGS的使用。

NPY_FALSE#

定义为0,用于与Bool一起使用。

NPY_TRUE#

定义为1,用于与Bool一起使用。

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,则此函数会清除标志,对 obj->base 调用 DECREF 并将其设置为可写,并将 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 顺序。

enumerator NPY_FORTRANORDER#

Fortran 顺序。

enumerator NPY_KEEPORDER#

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

enum NPY_CLIPMODE#

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

enumerator NPY_RAISE#

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

enumerator NPY_CLIP#

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

enumerator NPY_WRAP#

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

enum NPY_SEARCHSIDE#

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

enumerator NPY_SEARCHLEFT#
enumerator NPY_SEARCHRIGHT#
enum NPY_SELECTKIND#

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

enumerator NPY_INTROSELECT#
enum NPY_CASTING#

版本1.6中的新功能。

一个枚举类型,指示数据转换的允许程度。这由 NumPy 1.6 中添加的迭代器使用,并打算在未来的版本中更广泛地使用。

enumerator NPY_NO_CASTING#

只允许相同类型。

enumerator NPY_EQUIV_CASTING#

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

enumerator NPY_SAFE_CASTING#

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

enumerator NPY_SAME_KIND_CASTING#

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

enumerator NPY_UNSAFE_CASTING#

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