NumPy参考 >NumPy和SWIG > numpy.i:用于NumPy的SWIG接口文件
简单包装程序和接口生成器(或SWIG)是一个功能强大的工具,用于生成包装程序代码以与多种脚本语言接口。 SWIG可以解析头文件,并且仅使用代码原型创建目标语言的接口。但是SWIG并不是万能的。例如,它不能从原型中知道:
double rms(double* seq, int n);
到底seq
是什么 就地更改是单个值吗?它是数组吗?如果是,它的长度是多少?它是仅输入的吗?仅输出?输入输出? SWIG无法确定这些详细信息,也不会尝试这样做。
如果我们进行了设计rms
,则可能使它成为一个例程,该例程接受仅输入的长度n
为的double
值的数组,seq
并返回均方根。但是,SWIG的默认行为是创建一个包装函数,该函数可以进行编译,但是几乎不可能以脚本语言的预期方式使用C例程。
对于Python,使用NumPy处理同类数据的连续(或技术上为大跨步)块的首选方法
是使用NumPy,它提供了对多维数据数组的完全面向对象的访问。因此,该rms
函数最符合逻辑的Python接口为(包括doc字符串):
def rms(seq):
"""
rms: return the root mean square of a sequence
rms(numpy.ndarray) -> double
rms(list) -> double
rms(tuple) -> double
"""
其中seq
将是一个NumPy double
值数组,并且其长度n
将seq
在传递给C例程之前从内部提取。更好的是,由于NumPy支持从任意Python序列构造数组,因此seq
它本身可以是几乎任意的序列(只要每个元素都可以转换为double
),并且包装程序代码在提取其数据并在内部将其内部转换为NumPy数组之后,长度。
SWIG允许通过一种称为typemaps的机制来定义这些类型的转换。本文档提供有关如何使用的信息numpy.i
,SWIG接口文件定义了一系列类型映射,这些类型映射旨在使上述与数组相关的转换的类型相对容易实现。例如,假设rms
上面定义的函数原型在名为的头文件中rms.h
。要获取上面讨论的Python接口,您的
SWIG接口文件将需要以下内容:
%{
#define SWIG_FILE_WITH_INIT
#include "rms.h"
%}
%include "numpy.i"
%init %{
import_array();
%}
%apply (double* IN_ARRAY1, int DIM1) {(double* seq, int n)};
%include "rms.h"
类型映射从一个或多个函数参数的列表中键入(按类型或按类型和名称)。我们将这些列表称为
签名。numpy.i
上面使用了定义的许多类型映射之一,并且具有签名。参数名称旨在表明参数是一维的输入数组,并且表示该维的大小。这正是
原型中的模式。(double* IN_ARRAY1, int DIM1)
double*
int
rms
最有可能的是,没有要包装的实际原型具有参数名称IN_ARRAY1
和DIM1
。我们使用SWIG %apply
指令将类型为一维的输入数组的类型映射double
应用于所使用的实际原型rms
。numpy.i
因此,有效地使用它
需要知道哪些类型图可用以及它们做什么。
一个SWIG包含接口文件痛饮上面给出的指令会产生包装代码看起来是这样的:
1 PyObject *_wrap_rms(PyObject *args) {
2 PyObject *resultobj = 0;
3 double *arg1 = (double *) 0 ;
4 int arg2 ;
5 double result;
6 PyArrayObject *array1 = NULL ;
7 int is_new_object1 = 0 ;
8 PyObject * obj0 = 0 ;
9
10 if (!PyArg_ParseTuple(args,(char *)"O:rms",&obj0)) SWIG_fail;
11 {
12 array1 = obj_to_array_contiguous_allow_conversion(
13 obj0, NPY_DOUBLE, &is_new_object1);
14 npy_intp size[1] = {
15 -1
16 };
17 if (!array1 || !require_dimensions(array1, 1) ||
18 !require_size(array1, size, 1)) SWIG_fail;
19 arg1 = (double*) array1->data;
20 arg2 = (int) array1->dimensions[0];
21 }
22 result = (double)rms(arg1,arg2);
23 resultobj = SWIG_From_double((double)(result));
24 {
25 if (is_new_object1 && array1) Py_DECREF(array1);
26 }
27 return resultobj;
28 fail:
29 {
30 if (is_new_object1 && array1) Py_DECREF(array1);
31 }
32 return NULL;
33 }
from的类型映射numpy.i
负责以下代码行:12–20、25 和30。第10行分析rms
函数的输入。从格式字符串中"O:rms"
,我们可以看到参数列表应该是单个Python对象(由O
冒号之前的来指定),并且其指针存储在中
obj0
。numpy.i
调用了由提供的许多函数,以进行并检查从通用Python对象到NumPy数组的(可能)转换。这些功能在“ 助手功能 ”部分中进行了说明,但希望它们的名称不言自明。在第12行,我们使用obj0
构造一个NumPy数组。在第17行,我们检查结果的有效性:它为非null且具有任意长度的单个维。一旦验证了这些状态,我们将在第19行和第20行提取数据缓冲区和长度,以便可以在第22行调用基础C函数。对于创建了不再需要的新数组的情况,第25行执行内存管理。需要。
此代码具有大量错误处理。请注意,它
SWIG_fail
是for的宏,引用第28行的标签。如果用户提供了错误数量的参数,那么它将在第10行被捕获。如果NumPy数组的构造失败或生成的维数数量错误的数组,这些错误将在第17行捕获。最后,如果检测到错误,则在第30行仍然可以正确管理内存。goto fail
请注意,如果C函数签名的顺序不同:
double rms(int n, double* seq);
这SWIG将不匹配上面的参数列表给出的类型映射签名rms
。幸运的是,numpy.i
有一组类型映射,最后给出了数据指针:
%apply (int DIM1, double* IN_ARRAY1) {(int n, double* seq)};
这仅具有切换上面生成的代码的第3和4行中arg1
和的定义以及arg2
在第19和20行中它们的分配的效果。
该numpy.i
文件当前位于安装目录tools/swig
下的numpy
子目录中。通常,您需要将其复制到开发包装程序的目录中。
仅使用单个SWIG接口文件的简单模块应包括以下内容:
%{
#define SWIG_FILE_WITH_INIT
%}
%include "numpy.i"
%init %{
import_array();
%}
在已编译的Python模块中,import_array()
应仅被调用一次。这可能在您编写并链接到模块的C / C ++文件中。如果是这种情况,那么您的接口文件都不应该或不会调用
。或者,此初始化调用可以位于SWIG从具有上述块的接口文件
生成的包装文件中。如果是这种情况,并且您有多个SWIG接口文件,则仅一个接口文件应
调用。#define SWIG_FILE_WITH_INIT
import_array()
%init
#define SWIG_FILE_WITH_INIT
import_array()
除了C和NumPy类型规范外,由numpy.i
为不同数据类型(例如double
和)的数组int
和不同类型(例如int
或)的维提供的类型映射指令long
彼此相同。因此,类型映射是通过宏实现的(通常在幕后):
%numpy_typemaps(DATA_TYPE, DATA_TYPECODE, DIM_TYPE)
可以为适当的三元组调用。例如:(DATA_TYPE, DATA_TYPECODE,
DIM_TYPE)
%numpy_typemaps(double, NPY_DOUBLE, int)
%numpy_typemaps(int, NPY_INT , int)
该numpy.i
接口文件使用%numpy_typemaps
以实现用于下面的C数据类型和typemaps宏int
尺寸类型:
signed char
unsigned char
short
unsigned short
int
unsigned int
long
unsigned long
long long
unsigned long long
float
double
在下面的描述中,我们引用了generic DATA_TYPE
,它可以是上面列出的任何C数据类型,并且DIM_TYPE
应该是许多整数类型之一。
类型映射签名在给缓冲区指针的名称上有很大的区别。名称FARRAY
为Fortran排序的数组,名称ARRAY
为C排序(或1D数组)。
输入数组定义为传递到例程中但不会就地更改或返回给用户的数据数组。因此,Python输入数组几乎可以是任何可以转换为请求的数组类型的Python序列(例如列表)。输入数组签名为
1D:
( DATA_TYPE IN_ARRAY1[ANY] )
( DATA_TYPE* IN_ARRAY1, int DIM1 )
( int DIM1, DATA_TYPE* IN_ARRAY1 )
2D:
( DATA_TYPE IN_ARRAY2[ANY][ANY] )
( DATA_TYPE* IN_ARRAY2, int DIM1, int DIM2 )
( int DIM1, int DIM2, DATA_TYPE* IN_ARRAY2 )
( DATA_TYPE* IN_FARRAY2, int DIM1, int DIM2 )
( int DIM1, int DIM2, DATA_TYPE* IN_FARRAY2 )
3D:
( DATA_TYPE IN_ARRAY3[ANY][ANY][ANY] )
( DATA_TYPE* IN_ARRAY3, int DIM1, int DIM2, int DIM3 )
( int DIM1, int DIM2, int DIM3, DATA_TYPE* IN_ARRAY3 )
( DATA_TYPE* IN_FARRAY3, int DIM1, int DIM2, int DIM3 )
( int DIM1, int DIM2, int DIM3, DATA_TYPE* IN_FARRAY3 )
4D:
(DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY])
(DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
(DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, , DIM_TYPE DIM4, DATA_TYPE* IN_ARRAY4)
(DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
(DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_FARRAY4)
列出的第一个签名用于具有硬编码维的一维数组。同样,
对于具有硬编码维的二维数组,也适用于三维。( DATA_TYPE IN_ARRAY[ANY] )
( DATA_TYPE IN_ARRAY2[ANY][ANY] )
就地数组定义为就地修改的数组。输入值可以使用也可以不使用,但是函数返回时的值很重要。因此,提供的Python参数必须是所需类型的NumPy数组。就地签名是
1D:
( DATA_TYPE INPLACE_ARRAY1[ANY] )
( DATA_TYPE* INPLACE_ARRAY1, int DIM1 )
( int DIM1, DATA_TYPE* INPLACE_ARRAY1 )
2D:
( DATA_TYPE INPLACE_ARRAY2[ANY][ANY] )
( DATA_TYPE* INPLACE_ARRAY2, int DIM1, int DIM2 )
( int DIM1, int DIM2, DATA_TYPE* INPLACE_ARRAY2 )
( DATA_TYPE* INPLACE_FARRAY2, int DIM1, int DIM2 )
( int DIM1, int DIM2, DATA_TYPE* INPLACE_FARRAY2 )
3D:
( DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY] )
( DATA_TYPE* INPLACE_ARRAY3, int DIM1, int DIM2, int DIM3 )
( int DIM1, int DIM2, int DIM3, DATA_TYPE* INPLACE_ARRAY3 )
( DATA_TYPE* INPLACE_FARRAY3, int DIM1, int DIM2, int DIM3 )
( int DIM1, int DIM2, int DIM3, DATA_TYPE* INPLACE_FARRAY3 )
4D:
(DATA_TYPE INPLACE_ARRAY4[ANY][ANY][ANY][ANY])
(DATA_TYPE* INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
(DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, , DIM_TYPE DIM4, DATA_TYPE* INPLACE_ARRAY4)
(DATA_TYPE* INPLACE_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
(DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_FARRAY4)
现在,这些类型映射检查以确保INPLACE_ARRAY
参数使用本机字节顺序。如果不是,则引发异常。
还有一个“平面”原位数组,用于您要修改或处理每个元素的情况,而与尺寸的数量无关。一个示例是“量化”功能,该功能就地量化数组的每个元素,无论是1D,2D或其他任何元素。此表单检查连续性,但允许使用C或Fortran排序。
ND:
(DATA_TYPE* INPLACE_ARRAY_FLAT, DIM_TYPE DIM_FLAT)
Argout数组是出现在C输入参数中的数组,但实际上是输出数组。当有多个输出变量且因此单个返回参数不足时,通常会发生这种模式。在Python中,返回多个参数的常规方法是将它们打包成一个序列(元组,列表等)并返回该序列。这就是argout类型映射的作用。如果使用这些argout类型映射的包装函数具有多个返回参数,则它们将打包到一个元组或列表中,具体取决于Python的版本。Python用户不会传入这些数组,而只是返回它们。对于指定尺寸的情况,python用户必须提供该尺寸作为参数。argout签名是
1D:
( DATA_TYPE ARGOUT_ARRAY1[ANY] )
( DATA_TYPE* ARGOUT_ARRAY1, int DIM1 )
( int DIM1, DATA_TYPE* ARGOUT_ARRAY1 )
2D:
( DATA_TYPE ARGOUT_ARRAY2[ANY][ANY] )
3D:
( DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY] )
4D:
( DATA_TYPE ARGOUT_ARRAY4[ANY][ANY][ANY][ANY] )
这些通常用于在C / C ++中需要在堆上分配一个或多个数组并调用该函数以填充数组值的情况。在Python中,数组是为您分配的,并作为新的数组对象返回。
请注意,我们支持DATA_TYPE*
1D的argout类型映射,但不支持2D或3D。这是由于使用SWIG typemap语法的怪异而无法避免的。请注意,对于这些类型的一维类型映射,Python函数将使用一个表示的参数DIM1
。
Argoutview数组用于C代码为您提供其内部数据的视图,并且不需要用户分配任何内存。这可能很危险。几乎没有办法保证C代码的内部数据在封装它的NumPy数组的整个生命周期中都将一直存在。如果用户在销毁NumPy数组之前销毁了提供数据视图的对象,则使用该数组可能会导致错误的内存引用或分段错误。但是,在处理大型数据集的情况下,您别无选择。
要包装用于argoutview数组的C代码的特点是指针:指向维度的指针和指向数据的双指针,以便可以将这些值传递回用户。因此,argoutview typemap签名是
1D:
( DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1 )
( DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEW_ARRAY1 )
2D:
( DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2 )
( DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_ARRAY2 )
( DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2 )
( DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_FARRAY2 )
3D:
( DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
( DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_ARRAY3)
( DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
( DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_FARRAY3)
4D:
(DATA_TYPE** ARGOUTVIEW_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
(DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEW_ARRAY4)
(DATA_TYPE** ARGOUTVIEW_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
(DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEW_FARRAY4)
请注意,不支持具有硬编码维的数组。它们不能遵循这些类型映射的双指针签名。
numpy.i
类型映射的最新添加是允许带有视图的argout数组进入受管理的内存。请参阅此处的讨论。
1D:
(DATA_TYPE** ARGOUTVIEWM_ARRAY1, DIM_TYPE* DIM1)
(DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEWM_ARRAY1)
2D:
(DATA_TYPE** ARGOUTVIEWM_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
(DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_ARRAY2)
(DATA_TYPE** ARGOUTVIEWM_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
(DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_FARRAY2)
3D:
(DATA_TYPE** ARGOUTVIEWM_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
(DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEWM_ARRAY3)
(DATA_TYPE** ARGOUTVIEWM_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
(DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEWM_FARRAY3)
4D:
(DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
(DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_ARRAY4)
(DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
(DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_FARRAY4)
由于numpy.i
多种原因,该接口文件不支持输出数组的类型映射。首先,C / C ++返回参数限制为单个值。这阻止了以一般方式获得尺寸信息。其次,不允许将具有硬编码长度的数组作为返回参数。换一种说法:
double[3] newVector(double x, double y, double z);
不是合法的C / C ++语法。因此,我们不能提供以下形式的类型映射:
%typemap(out) (TYPE[ANY]);
如果碰上其中一个函数或方法返回一个指向数组的指针的情况下,最好的办法是写自己的版本的函数被包裹,要么%extend
为类方法或情况%ignore
和%rename
对功能的情况下, 。
请注意,bool
“ 可用类型映射”部分的列表中不支持
C ++类型。NumPy布尔是一个字节,而C ++ bool
是四个字节(至少在我的系统上)。因此:
%numpy_typemaps(bool, NPY_BOOL, int)
将导致类型映射产生将引用不正确的数据长度的代码。您可以实现以下宏扩展:
%numpy_typemaps(bool, NPY_UINT, int)
还不自动支持复杂浮点类型的Typemap转换。这是因为Python和NumPy是用C编写的,它没有本机复杂类型。Python和NumPy都struct
为复杂变量实现了自己的(基本上等效的)
定义:
/* Python */
typedef struct {double real; double imag;} Py_complex;
/* NumPy */
typedef struct {float real, imag;} npy_cfloat;
typedef struct {double real, imag;} npy_cdouble;
我们可以实现:
%numpy_typemaps(Py_complex , NPY_CDOUBLE, int)
%numpy_typemaps(npy_cfloat , NPY_CFLOAT , int)
%numpy_typemaps(npy_cdouble, NPY_CDOUBLE, int)
这将提供自动类型转换为类型的阵列Py_complex
,npy_cfloat
和npy_cdouble
。但是,似乎不太可能会有人们使用SWIG生成Python接口的任何独立(非Python,非NumPy)应用程序代码,这些代码也将这些定义用于复杂类型。这些应用程序代码将更有可能定义自己的复杂类型,或者在C ++中使用use std::complex
。假设这些数据结构与Python和NumPy复杂类型兼容,则%numpy_typemap
上述扩展(将用户的复杂类型替换为第一个参数)应该有效。
SWIG具有用于数字类型的复杂类型检查。例如,如果您的C / C ++例程期望输入整数,则SWIG生成的代码将同时检查Python整数和Python长整数,如果提供的Python整数太大而无法转换为C,则会引发溢出错误。整数。随着NumPy标量数组在Python代码中的引入,您可能会想到从NumPy数组中提取一个整数,然后尝试将其传递给SWIG封装的C / C ++函数,该函数需要一个
int
,但SWIG类型检查不会将NumPy数组标量识别为整数。(通常,这实际上是可行的–它取决于NumPy是否将使用的整数类型识别为从使用的平台上的Python整数类型继承。有时,这意味着在32位计算机上工作的代码将在64位计算机上失败。)
如果您收到类似以下内容的Python错误:
TypeError: in method 'MyClass_MyMethod', argument 2 of type 'int'
并且您传递的参数是从NumPy数组中提取的整数,那么您偶然发现了这个问题。解决方案是修改SWIG类型转换系统,以接受除标准整数类型之外的NumPy数组标量。幸运的是,已经为您提供了此功能。只需复制文件:
pyfragments.swg
到项目的工作生成目录中,此问题将得到解决。建议您还是这样做,因为这只会增加Python接口的功能。
所述SWIG类型检查和转换系统是C宏的复杂组合SWIG宏SWIG typemaps和SWIG 片段。片段是一种在需要时有条件地将代码插入包装文件的方法,而在不需要时则不插入代码。如果多个类型映射需要相同的片段,则该片段仅被插入到您的包装器代码中一次。
有一个将Python整数转换为C的片段
long
。有一个不同的片段将Python整数转换为C int
,该long
片段调用该片段中定义的例程
。我们可以通过更改long
片段的定义来进行所需的更改。 SWIG使用“先到先得”系统确定片段的有效定义。也就是说,long
在SWIG内部进行转换之前,我们需要为转换定义片段。 SWIG允许我们通过将片段定义放入文件中来执行此操作
pyfragments.swg
。如果我们将新的片段定义放在中numpy.i
,它们将被忽略。
该numpy.i
文件包含多个宏和例程,这些宏和例程在内部用于构建其类型映射。但是,这些功能在界面文件中的其他位置可能很有用。这些宏和例程作为片段实现,在上一节中进行了简要描述。如果尝试使用以下一个或多个宏或函数,但是编译器抱怨它无法识别该符号,则需要使用以下命令强制这些片段出现在代码中:
%fragment("NumPy_Fragments");
在您的SWIG界面文件中。
- is_array(a)
如果
a
为非NULL
,则评估为true,并且可以将其强制转换为PyArrayObject*
。- array_type(a)
a
假定a
可以转换为,则求值为整数数据类型代码PyArrayObject*
。- array_numdims(a)
a
假定a
可以转换为,则 计算为维的整数PyArrayObject*
。- array_dimensions(a)
评估为类型
npy_intp
和长度的数组,并 假定可以转换为array_numdims(a)
,给出所有维度的长度。a
a
PyArrayObject*
- array_size(a,i)
假设 可以转换
i
为a
,则计算为的第-个维度尺寸。a
PyArrayObject*
- array_strides(a)
评估为类型
npy_intp
和长度的数组,并 假定可以array_numdims(a)
转换为,从而给出的所有尺寸的步幅。跨度是沿同一轴的元素与其紧邻元素之间的距离(以字节为单位)。a
a
PyArrayObject*
- array_stride(a,i)
假设可以强制转换为的
i
第一个大步。a
a
PyArrayObject*
- array_data(a)
假设可以将类型转换为
void*
,指向指向的数据缓冲区的类型的指针。a
a
PyArrayObject*
- array_descr(a)
假设可以转换
PyArray_Descr*
为a
,则返回对的dtype属性()的借用引用。a
PyArrayObject*
- array_flags(a)
返回一个整数,表示的标志
a
,假设a
可以将其强制转换为PyArrayObject*
。- array_enableflags(a,f)
设置由
Numpy 中文网