Spec-Zone.ru › NumPy 1.10

Типы Python и C-структуры

В коде C определено несколько новых типов. Большинство из них доступны из Python, но некоторые не экспонируются из-за ограниченного использования. Каждый новый тип Python связан с PyObject * и имеет внутреннюю структуру, которая включает указатель на «таблицу методов», определяющую поведение нового объекта в Python. При получении объекта Python в код C вы всегда получаете указатель на структуру PyObject. Поскольку структура PyObject очень общая и определяет только PyObject_HEAD, сама по себе она не очень интересна. Однако разные объекты содержат больше деталей после PyObject_HEAD (но вам нужно выполнить приведение к нужному типу, чтобы получить к ним доступ — или использовать функции-аксессоры или макросы).

Определённые новые типы Python

Типы Python — это функциональный эквивалент классов в Python в C. Создавая новый тип Python, вы делаете доступным новый объект для Python. Объект ndarray является примером нового типа, определённого в C. Новые типы определяются в C двумя основными шагами:

  1. создание C-структуры (обычно с именем Py{Name}Object), которая бинарно совместима со структурой PyObject, но содержит дополнительную информацию, необходимую для этого конкретного объекта;
  2. заполнение таблицы PyTypeObject (на которую указывает член ob_type структуры PyObject) указателями на функции, которые реализуют желаемое поведение для типа.

Вместо специальных имён методов, которые определяют поведение для классов Python, существуют «таблицы функций», которые указывают на функции, которые реализуют желаемые результаты. Начиная с Python 2.2, сам PyTypeObject стал динамическим, что позволяет типам C, которые могут быть «подтипами» других типов C в C и подклассами в Python. Дочерние типы наследуют атрибуты и методы от своих родительских типов.

Существует два основных новых типа: ndarray ( PyArray_Type ) и ufunc ( PyUFunc_Type ). Дополнительные типы играют вспомогательную роль: PyArrayIter_Type, PyArrayMultiIter_Type, и PyArrayDescr_Type. PyArrayIter_Type — это тип плоского итератора для ndarray (объект, который возвращается при получении атрибута flat). PyArrayMultiIter_Type — это тип объекта, возвращаемого при вызове broadcast (). Он обрабатывает итерацию и трансляцию по набору вложенных последовательностей. Также PyArrayDescr_Type — это тип описателя типа данных, экземпляры которого описывают данные. Наконец, есть 21 новый скалярный тип массива, которые являются новыми скалярами Python, соответствующими каждому из основных типов данных, доступных для массивов. Ещё 10 типов являются заглушками, которые позволяют скалярам массива вписаться в иерархию реальных типов Python.

Тип PyArray_Type

PyArrayObject

C-структура PyArrayObject содержит всю необходимую информацию для массива. Все экземпляры ndarray (и его подклассов) будут иметь эту структуру. Для обеспечения будущей совместимости члены этой структуры обычно должны вызываться с помощью предоставленных макросов. Если вам нужно более короткое имя, вы можете использовать NPY_AO, которое определено как эквивалентное PyArrayObject.

typedef struct PyArrayObject {
    PyObject_HEAD
    char *data;
    int nd;
    npy_intp *dimensions;
    npy_intp *strides;
    PyObject *base;
    PyArray_Descr *descr;
    int flags;
    PyObject *weakreflist;
} PyArrayObject;
char *PyArrayObject.data

Указатель на первый элемент массива. Этот указатель можно (и обычно следует) привести к типу данных массива.

int PyArrayObject.nd

Целое число, определяющее количество измерений для этого массива. Когда nd равно 0, массив иногда называют массивом ранга 0. Такие массивы имеют неопределённые размеры и шаги и недоступны. NPY_MAXDIMS — это максимальное количество измерений для любого массива.

npy_intp PyArrayObject.dimensions

Массив целых чисел, предоставляющий форму в каждом измерении, пока nd \geq 1. Целое число всегда достаточно велико, чтобы содержать указатель на платформе, поэтому размер измерения ограничен только памятью.

npy_intp *PyArrayObject.strides

Массив целых чисел, предоставляющий для каждого измерения количество байт, которое необходимо пропустить, чтобы перейти к следующему элементу в этом измерении.

PyObject *PyArrayObject.base

Этот член используется для хранения указателя на другой объект Python, связанный с этим массивом. Существует два случая использования: 1) Если этот массив не владеет своей собственной памятью, то base указывает на объект Python, который им владеет (возможно, другой объект массива), 2) Если для этого массива установлен флаг NPY_ARRAY_UPDATEIFCOPY, то этот массив является рабочей копией «неправильного» массива. Как только этот массив будет удалён, массив, на который указывает base, будет обновлён содержимым этого массива.

PyArray_Descr *PyArrayObject.descr

Указатель на объект-описатель типа данных (см. ниже). Объект-описатель типа данных — это экземпляр нового встроенного типа, который позволяет генерически описывать память. Существует структура описателя для каждого поддерживаемого типа данных. Эта структура описателя содержит полезную информацию о типе, а также указатель на таблицу указателей на функции для реализации конкретной функциональности.

int PyArrayObject.flags

Флаги, указывающие, как интерпретировать память, на которую указывает data. Возможные флаги — NPY_ARRAY_C_CONTIGUOUS, NPY_ARRAY_F_CONTIGUOUS, NPY_ARRAY_OWNDATA, NPY_ARRAY_ALIGNED, NPY_ARRAY_WRITEABLE и NPY_ARRAY_UPDATEIFCOPY.

PyObject *PyArrayObject.weakreflist

Этот член позволяет объектам массивов иметь слабые ссылки (используя модуль weakref).

Тип PyArrayDescr_Type

PyArray_Descr

Формат структуры PyArray_Descr, лежащей в основе PyArrayDescr_Type, таков:

typedef struct {
    PyObject_HEAD
    PyTypeObject *typeobj;
    char kind;
    char type;
    char byteorder;
    char unused;
    int flags;
    int type_num;
    int elsize;
    int alignment;
    PyArray_ArrayDescr *subarray;
    PyObject *fields;
    PyArray_ArrFuncs *f;
} PyArray_Descr;
PyTypeObject *PyArray_Descr.typeobj

Указатель на typeobject, который является соответствующим типом Python для элементов этого массива. Для встроенных типов он указывает на соответствующий скаляр массива. Для типов, определённых пользователем, он должен указывать на объект typeobject, определённый пользователем. Этот объект typeobject может либо наследоваться от скаляров массива, либо нет. Если он не наследуется от скаляров массива, то флаги NPY_USE_GETITEM и NPY_USE_SETITEM должны быть установлены в члене flags.

char PyArray_Descr.kind

Символьный код, указывающий тип массива (используя обозначение строчных типов интерфейса массива). ‘b’ — булево, ‘i’ — целое со знаком, ‘u’ — целое без знака, ‘f’ — с плавающей точкой, ‘c’ — комплексное с плавающей точкой, ‘S’ — строка символов размером 8 бит, ‘U’ — строка символов Юникода размером 32 бита, а ‘V’ — произвольный.

char PyArray_Descr.type

Традиционный символьный код, указывающий тип данных.

char PyArray_Descr.byteorder

Символ, указывающий порядок байтов: ‘>’ (big-endian), ‘<’ (little-endian), ‘=’ (родной), ‘|’ (нерелевантный, игнорировать). У всех встроенных типов данных порядок байтов равен ‘=’.

int PyArray_Descr.flags

Флаг типа данных, определяющий, демонстрирует ли тип данных поведение, похожее на массив объектов. Каждый бит в этом члене — это флаг, имеющий следующие имена:

PyDataType_FLAGCHK(PyArray_Descr *dtype, int flags)

Возвращает true, если все заданные флаги установлены для объекта типа данных.

PyDataType_REFCHK(PyArray_Descr *dtype)

Эквивалентно PyDataType_FLAGCHK (dtype, NPY_ITEM_REFCOUNT).

int PyArray_Descr.type_num

Число, уникально идентифицирующее тип данных. Для новых типов данных это число назначается при регистрации типа данных.

int PyArray_Descr.elsize

Для типов данных, которые всегда имеют одинаковый размер (например, long), это размер типа данных. Для гибких типов данных, где разные массивы могут иметь разные размеры элементов, это должно быть 0.

int PyArray_Descr.alignment

Число, предоставляющее информацию об выравнивании для этого типа данных. В частности, оно показывает, как далеко от начала структуры из двух элементов (первый элемент которой — char ), компилятор помещает элемент этого типа: offsetof(struct {char c; type v;}, v)

PyArray_ArrayDescr *PyArray_Descr.subarray

Если это не NULL, то этот дескриптор типа данных представляет собой непрерывный массив C-стиля другого дескриптора типа данных. Другими словами, каждый элемент, описываемый этим дескриптором, фактически является массивом некоторого другого базового дескриптора. Это наиболее полезно в качестве дескриптора типа данных для поля в другом дескрипторе типа данных. Члены поля должны быть NULL если это не NULL (член поля базового дескриптора может быть не NULL, однако). Структура PyArray_ArrayDescr определена с помощью

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

Элементы этой структуры:

PyArray_Descr *PyArray_ArrayDescr.base

Объект дескриптора типа данных базового типа.

PyObject *PyArray_ArrayDescr.shape

Форма (всегда непрерывная в стиле C) подмассива в виде кортежа Python.

PyObject *PyArray_Descr.fields

Если это не NULL, то этот дескриптор типа данных имеет поля, описанные в словаре Python, ключами которого являются имена (а также заголовки, если они указаны), а значениями — кортежи, описывающие поля. Обратите внимание, что дескриптор типа данных всегда описывает фиксированный набор байтов. Поле — это именованная подобласть этого полного, фиксированного набора. Поле описывается кортежем, состоящим из другого дескриптора типа данных и смещения байта. По желанию, кортеж может содержать заголовок, который обычно является строкой Python. Эти кортежи размещаются в этом словаре с ключами по имени (и также по заголовку, если он указан).

PyArray_ArrFuncs *PyArray_Descr.f

Указатель на структуру, содержащую функции, которые тип должен реализовывать для внутренних функций. Эти функции не являются тем же, что универсальные функции (ufuncs), описанные позже. Их сигнатуры могут произвольно отличаться.

PyArray_ArrFuncs

Функции, реализующие внутренние возможности. Не все эти указатели на функции должны быть определены для данного типа. Требуемыми членами являются nonzero, copyswap, copyswapn, setitem, getitem, и cast. Предполагается, что они не NULL и NULL записи приведут к аварийному завершению программы. Другие функции могут быть NULL что просто означает уменьшенную функциональность для этого типа данных. (Также, функция nonzero будет заполнена по умолчанию, если она NULL при регистрации пользовательского типа данных).

typedef struct {
    PyArray_VectorUnaryFunc *cast[NPY_NTYPES];
    PyArray_GetItemFunc *getitem;
    PyArray_SetItemFunc *setitem;
    PyArray_CopySwapNFunc *copyswapn;
    PyArray_CopySwapFunc *copyswap;
    PyArray_CompareFunc *compare;
    PyArray_ArgFunc *argmax;
    PyArray_DotFunc *dotfunc;
    PyArray_ScanFunc *scanfunc;
    PyArray_FromStrFunc *fromstr;
    PyArray_NonzeroFunc *nonzero;
    PyArray_FillFunc *fill;
    PyArray_FillWithScalarFunc *fillwithscalar;
    PyArray_SortFunc *sort[NPY_NSORTS];
    PyArray_ArgSortFunc *argsort[NPY_NSORTS];
    PyObject *castdict;
    PyArray_ScalarKindFunc *scalarkind;
    int **cancastscalarkindto;
    int *cancastto;
    PyArray_FastClipFunc *fastclip;
    PyArray_FastPutmaskFunc *fastputmask;
    PyArray_FastTakeFunc *fasttake;
    PyArray_ArgFunc *argmin;
} PyArray_ArrFuncs;

В описании указателей на функции используется понятие корректного сегмента. Корректный сегмент — это сегмент, выровненный и в родном порядке байтов для данного типа данных. Функции nonzero, copyswap, copyswapn, getitem, и setitem могут (и должны) обрабатывать некорректные массивы. Другие функции требуют корректных участков памяти.

void cast(void *from, void *to, npy_intp n, void *fromarr, void *toarr)

Массив указателей на функции для преобразования из текущего типа во все другие встроенные типы. Каждая функция преобразует непрерывный, выровненный и необращенный буфер, указанный в from, в непрерывный, выровненный и необращенный буфер, указанный в to. Количество элементов для преобразования задаётся значением n, а аргументы fromarr и toarr интерпретируются как PyArrayObjects для гибких массивов, чтобы получить информацию о размере элемента.

PyObject *getitem(void *data, void *arr)

Указатель на функцию, возвращающую стандартный объект Python из одного элемента объекта массива arr, на который указывает data. Эта функция должна уметь правильно обрабатывать «некорректные» (невыровненные и/или с изменённым порядком байтов) массивы.

int setitem(PyObject *item, void *data, void *arr)

Указатель на функцию, устанавливающую объект Python item в массив arr в позиции, на которую указывает data. Эта функция обрабатывает «некорректные» массивы. При успешном выполнении возвращается ноль, в противном случае — минус один (и устанавливается ошибка Python).

void copyswapn(void *dest, npy_intp dstride, void *src, npy_intp sstride, npy_intp n, int swap, void *arr)
void copyswap(void *dest, void *src, int swap, void *arr)

Эти члены — оба указателя на функции для копирования данных из src в dest и swap, если это указано. Значение arr используется только для гибких ( NPY_STRING, NPY_UNICODE и NPY_VOID ) массивов (и получается из arr->descr->elsize ). Вторая функция копирует одно значение, а первая повторяет эту операцию n раз со заданными шагами. Эти функции могут обрабатывать некорректные данные src. Если src равно NULL, то копирование не выполняется. Если swap равно 0, то перестановка байтов не происходит. Предполагается, что dest и src не перекрываются. Если они перекрываются, то сначала используйте memmove (…), а затем copyswap(n) с src значением NULL.

int compare(const void* d1, const void* d2, void* arr)

Указатель на функцию, сравнивающую два элемента массива, arr, указанных по адресу d1 и d2. Эта функция требует корректных (выровненных и без перестановки байтов) массивов. Возвращаемое значение равно 1, если * d1 > * d2, 0, если * d1 == * d2, и -1, если * d1 < * d2. Объект массива arr используется для получения информации о размере элемента и поле для гибких массивов.

int argmax(void* data, npy_intp n, npy_intp* max_ind, void* arr)

Указатель на функцию, возвращающую индекс наибольшего из n элементов в arr, начиная с элемента, на который указывает data. Эта функция требует, чтобы участок памяти был непрерывным и корректным. Возвращаемое значение всегда равно 0. Индекс наибольшего элемента возвращается в max_ind.

void dotfunc(void* ip1, npy_intp is1, void* ip2, npy_intp is2, void* op, npy_intp n, void* arr)

Указатель на функцию, которая перемножает две n -длинные последовательности, складывает их и помещает результат в элемент, указанный по адресу op массива arr. Начало двух последовательностей указаны по адресам ip1 и ip2 . Для перехода к следующему элементу в каждой последовательности требуется перескок на is1 и is2 байтов, соответственно. Эта функция требует корректной (хотя и не обязательно непрерывной) памяти.

int scanfunc(FILE* fd, void* ip, void* sep, void* arr)

Указатель на функцию, которая выполняет сканирование (подобно scanf) одного элемента соответствующего типа из дескриптора файла fd в память массива, на которую указывает ip. Массив предполагается корректным. Если sep не равно NULL, то также сканируется разделительная строка из файла перед возвратом. Последний аргумент arr — массив, в который производится сканирование. Возвращается 0, если сканирование прошло успешно. Отрицательное число указывает на ошибку: -1 означает, что конец файла был достигнут до сканирования разделительной строки, -4 означает, что конец файла был достигнут до сканирования элемента, и -3 означает, что элемент не мог быть интерпретирован из строки формата. Требуется корректный массив.

int fromstr(char* str, void* ip, char** endptr, void* arr)

Указатель на функцию, которая преобразует строку, на которую указывает str, в один элемент соответствующего типа и помещает его в место в памяти, указанное по адресу ip. После завершения преобразования *endptr указывает на оставшуюся часть строки. Последний аргумент arr — массив, в который указывает ip (необходим для массивов с переменным размером).

Bool nonzero(void* data, void* arr)

Указатель на функцию, возвращающую TRUE, если элемент массива arr, на который указывает data, не равен нулю. Эта функция может обрабатывать некорректные массивы.

void fill(void* data, npy_intp length, void* arr)

Указатель на функцию, заполняющую непрерывный массив заданной длины данными. Первые два элемента массива должны быть заполнены. Из этих двух значений будет вычислена разность, и значения с элемента 3 до конца будут вычисляться путём последовательного добавления этой разности. Буфер данных должен быть корректным.

void fillwithscalar(void* buffer, npy_intp length, void* value, void* arr)

Указатель на функцию, заполняющую непрерывный buffer заданного length с помощью одного скалярного value, адрес которого указан. Последний аргумент — массив, необходимый для получения размера элемента для массивов переменной длины.

int sort(void* start, npy_intp length, void* arr)

Массив указателей на функции для конкретного алгоритма сортировки. Конкретный алгоритм сортировки выбирается по ключу (на данный момент определены NPY_QUICKSORT, :data`NPY_HEAPSORT`, и NPY_MERGESORT). Сортировка выполняется на месте, предполагается непрерывность и выравнивание данных.

int argsort(void* start, npy_intp* result, npy_intp length, void *arr)

Массив указателей на функции сортировки для этого типа данных. Доступны те же алгоритмы сортировки, что и для sort. Индексы, порождающие сортировку, возвращаются в result (который должен быть инициализирован индексами от 0 до length-1 включительно).

PyObject *castdict

Либо NULL, либо словарь, содержащий функции низкоуровневого преобразования для пользовательских типов данных. Каждая функция обернута в PyCObject * и имеет в качестве ключа номер типа данных.

NPY_SCALARKIND scalarkind(PyArrayObject* arr)

Функция для определения того, как следует интерпретировать скаляры этого типа. Аргумент — NULL или одномерный массив, содержащий данные (если это необходимо для определения типа скаляра). Возвращаемое значение должно иметь тип NPY_SCALARKIND.

int **cancastscalarkindto

Либо NULL, либо массив указателей NPY_NSCALARKINDS. Каждый из этих указателей должен быть либо NULL, либо указателем на массив целых чисел (завершаемых NPY_NOTYPE), указывающих на типы данных, в которые скаляр этого типа данных указанного типа может быть безопасно преобразован (обычно это означает без потери точности).

int *cancastto

Либо NULL, либо массив целых чисел (завершаемый NPY_NOTYPE), указывающий на типы данных, в которые этот тип данных может быть безопасно преобразован (обычно это означает без потери точности).

void fastclip(void *in, npy_intp n_in, void *min, void *max, void *out)

Функция, которая считывает n_in элементов из in, и записывает в out считанное значение, если оно находится в пределах, указанных по адресам min и max, или соответствующее ограничение, если оно находится вне пределов. Участки памяти должны быть непрерывными и корректными, и либо min , либо max может быть NULL, но не оба одновременно.

void fastputmask(void *in, void *mask, npy_intp n_in, void *values, npy_intp nv)

Функция, принимающая указатель in на массив элементов типа n_in, указатель mask на массив булевых значений, и указатель vals на массив элементов типа nv. Элементы из vals копируются в in там, где значение в mask не равно нулю, с повторением vals при необходимости, если nv < n_in. Все массивы должны быть непрерывными и вежливыми.

void fasttake(void *dest, void *src, npy_intp *indarray, npy_intp nindarray, npy_intp n_outer, npy_intp m_middle, npy_intp nelem, NPY_CLIPMODE clipmode)

Функция, принимающая указатель src на непрерывный, вежливый фрагмент, интерпретируемый как 3-мерный массив формы (n_outer, nindarray, nelem), указатель indarray на непрерывный, вежливый фрагмент целочисленных индексов, и указатель dest на непрерывный, вежливый фрагмент, интерпретируемый как 3-мерный массив формы (n_outer, m_middle, nelem). Индексы в indarray используются для индексирования src по второму измерению, и копирования соответствующих фрагментов элементов nelem в dest. clipmode (которое может принимать значения NPY_RAISE, NPY_WRAP или NPY_CLIP) определяет, как будут обрабатываться индексы, меньшие 0 или большие nindarray.

int argmin(void* data, npy_intp n, npy_intp* min_ind, void* arr)

Указатель на функцию, которая возвращает индекс наименьшего из n элементов в arr, начиная с элемента, на который указывает data. Эта функция требует, чтобы сегмент памяти был непрерывным и вежливым. Значение возврата всегда равно 0. Индекс наименьшего элемента возвращается в min_ind.

Тип PyArray_Type реализует многие функции объектов Python, включая интерфейсы tp_as_number, tp_as_sequence, tp_as_mapping и tp_as_buffer. Также используется богатое сравнение (tp_richcompare), наряду с поиском атрибутов нового стиля для методов (tp_methods) и свойств (tp_getset). Тип PyArray_Type также может быть подтипом.

Подсказка

Методы tp_as_number используют общий подход для вызова любой функции, которая была зарегистрирована для обработки операции. Функция PyNumeric_SetOps(..) может использоваться для регистрации функций для обработки конкретных математических операций (для всех массивов). При импорте модуля umath, он устанавливает числовые операции для всех массивов на соответствующие ufuncs. Методы tp_str и tp_repr также могут быть изменены с помощью PyString_SetStringFunction(...).

PyUFunc_Type

PyUFuncObject

Ядром ufunc является PyUFuncObject, который содержит всю информацию, необходимую для вызова подлежащих C-кодовых циклов, выполняющих фактическую работу. Он имеет следующую структуру:

typedef struct {
    PyObject_HEAD
    int nin;
    int nout;
    int nargs;
    int identity;
    PyUFuncGenericFunction *functions;
    void **data;
    int ntypes;
    int check_return;
    const char *name;
    char *types;
    const char *doc;
    void *ptr;
    PyObject *obj;
    PyObject *userloops;
    npy_uint32 *op_flags;
    npy_uint32 *iter_flags;
} PyUFuncObject;
int PyUFuncObject.nin

Количество входных аргументов.

int PyUFuncObject.nout

Количество выходных аргументов.

int PyUFuncObject.nargs

Общее количество аргументов (nin + nout). Это значение должно быть меньше NPY_MAXARGS.

int PyUFuncObject.identity

Либо PyUFunc_One, либо PyUFunc_Zero, либо PyUFunc_None для обозначения единицы для этой операции. Она используется только для вызова типа reduce на пустом массиве.

void PyUFuncObject.functions(char** args, npy_intp* dims,
npy_intp* steps, void* extradata)

Массив указателей на функции — по одному для каждого поддерживаемого типа данных ufunc. Это цикл векторов, который вызывается для реализации подлежащей функции dims [0] раз. Первый аргумент, args, представляет собой массив из nargs указателей на вежливую память. Указатели на данные для входных аргументов находятся первыми, за ними следуют указатели на данные для выходных аргументов. Количество байтов, которое необходимо пропустить, чтобы получить следующий элемент в последовательности, задается соответствующим элементом в массиве steps. Последний аргумент позволяет циклу получать дополнительную информацию. Это обычно используется, чтобы один общий цикл векторов мог использоваться для нескольких функций. В этом случае фактическая скалярная функция, которую нужно вызвать, передается в качестве extradata. Размер этого массива указателей на функции равен ntypes.

void **PyUFuncObject.data

Дополнительные данные, которые необходимо передать циклам векторов 1-d, или NULL если дополнительные данные не нужны. Этот массив C должен быть того же размера (т.е. ntypes) что и массив функций. NULL используется, если дополнительные данные не нужны. Несколько вызовов C-API для UFuncs представляют собой циклы векторов 1-d, которые используют эти дополнительные данные для получения указателя на фактическую вызываемую функцию.

int PyUFuncObject.ntypes

Количество поддерживаемых типов данных для ufunc. Это число определяет количество различных циклов 1-d (встроенных типов данных), которые доступны.

int PyUFuncObject.check_return

Устаревший и неиспользуемый. Однако он устанавливается соответствующим элементом в основной процедуре создания ufunc: PyUFunc_FromFuncAndData (...).

char *PyUFuncObject.name

Строковое имя для ufunc. Это используется динамически для построения атрибута __doc__ для ufuncs.

char *PyUFuncObject.types

Массив из nargs \times ntypes 8-битных номеров типов, который содержит сигнатуру типа для функции для каждого из поддерживаемых (встроенных) типов данных. Для каждой из ntypes функций, соответствующий набор номеров типов в этом массиве показывает, как аргумент args должен интерпретироваться в цикле векторов 1-d. Эти номера типов не должны быть одинаковыми, и ufuncs смешанных типов поддерживаются.

char *PyUFuncObject.doc

Документация для ufunc. Не должна содержать сигнатуру функции, так как она генерируется динамически при получении __doc__.

void *PyUFuncObject.ptr

Любая динамически выделенная память. В настоящее время используется для динамически созданных ufuncs из python-функций для хранения места для членов types, data и name.

PyObject *PyUFuncObject.obj

Для ufuncs, динамически созданных из python-функций, этот член содержит ссылку на подлежащую Python-функцию.

PyObject *PyUFuncObject.userloops

Словарь пользовательских циклов векторов 1-d (хранящихся как указатели CObject) для пользовательских типов. Пользователь может зарегистрировать цикл для любого пользовательского типа. Он извлекается по номеру типа. Номера типов пользовательского определения всегда больше NPY_USERDEF.

npy_uint32 PyUFuncObject.op_flags

Переопределяет флаги операндов по умолчанию для каждого операнда ufunc.

npy_uint32 PyUFuncObject.iter_flags

Переопределяет флаги nditer по умолчанию для ufunc.

PyArrayIter_Type

PyArrayIterObject

Структура C, соответствующая объекту PyArrayIter_Type — это PyArrayIterObject. PyArrayIterObject используется для отслеживания указателя на элемент N-мерного массива. Он содержит связанную информацию, используемую для быстрого перемещения по массиву. Указатель можно изменить тремя основными способами: 1) перейти к следующему элементу массива в стиле C с последовательным доступом, 2) перейти к произвочным N-мерным координатам в массиве и 3) перейти к произвольному одномерному индексу в массиве. Члены структуры PyArrayIterObject используются в этих расчётах. Объекты-итераторы сохраняют собственные размерности и шаги массива. Это можно изменять по мере необходимости для «вещания» или для обхода только определённых измерений.

typedef struct {
    PyObject_HEAD
    int   nd_m1;
    npy_intp  index;
    npy_intp  size;
    npy_intp  coordinates[NPY_MAXDIMS];
    npy_intp  dims_m1[NPY_MAXDIMS];
    npy_intp  strides[NPY_MAXDIMS];
    npy_intp  backstrides[NPY_MAXDIMS];
    npy_intp  factors[NPY_MAXDIMS];
    PyArrayObject *ao;
    char  *dataptr;
    Bool  contiguous;
} PyArrayIterObject;
int PyArrayIterObject.nd_m1

N-1 где N — количество измерений в базовом массиве.

npy_intp PyArrayIterObject.index

Текущий одномерный индекс в массиве.

npy_intp PyArrayIterObject.size

Общий размер базового массива.

npy_intp *PyArrayIterObject.coordinates

N-мерный индекс в массиве.

npy_intp *PyArrayIterObject.dims_m1

Размер массива минус 1 в каждом измерении.

npy_intp *PyArrayIterObject.strides

Шаги массива. Сколько байт нужно перейти к следующему элементу в каждом измерении.

npy_intp *PyArrayIterObject.backstrides

Сколько байт нужно перейти от конца измерения к его началу. Обратите внимание, что backstrides [k]= strides [k]*d ims_m1 [k], но это хранится здесь для оптимизации.

npy_intp *PyArrayIterObject.factors

Этот массив используется для вычисления N-мерного индекса из одномерного индекса. Он содержит необходимые произведения размерностей.

PyArrayObject *PyArrayIterObject.ao

Указатель на базовый ndarray, для представления которого был создан этот итератор.

char *PyArrayIterObject.dataptr

Этот член указывает на элемент в ndarray, указанный индексом.

Bool PyArrayIterObject.contiguous

Этот флаг имеет значение true, если базовый массив является NPY_ARRAY_C_CONTIGUOUS. Он используется для упрощения расчётов, когда это возможно.

Более подробное объяснение использования итератора массива на уровне C приведено в следующих разделах. Как правило, вам не нужно беспокоиться о внутренней структуре объекта-итератора, а просто взаимодействовать с ним с помощью макросов PyArray_ITER_NEXT (it), PyArray_ITER_GOTO (it, dest) или PyArray_ITER_GOTO1D (it, index). Все эти макросы требуют аргумента it, который должен быть PyArrayIterObject *.

PyArrayMultiIter_Type

PyArrayMultiIterObject
typedef struct {
    PyObject_HEAD
    int numiter;
    npy_intp size;
    npy_intp index;
    int nd;
    npy_intp dimensions[NPY_MAXDIMS];
    PyArrayIterObject *iters[NPY_MAXDIMS];
} PyArrayMultiIterObject;
int PyArrayMultiIterObject.numiter

Количество массивов, которые необходимо привести к одному размеру.

npy_intp PyArrayMultiIterObject.size

Общий размер после вещания.

npy_intp PyArrayMultiIterObject.index

Текущий (одномерный) индекс в результирующем массиве после вещания.

int PyArrayMultiIterObject.nd

Количество измерений в результирующем массиве после вещания.

npy_intp *PyArrayMultiIterObject.dimensions

Размеры результирующего массива после вещания (используются только nd слоты).

PyArrayIterObject **PyArrayMultiIterObject.iters

Массив объектов-итераторов, содержащий итераторы для массивов, которые необходимо привести к одному размеру. После возвращения итераторы корректируются для вещания.

PyArrayNeighborhoodIter_Type

PyArrayNeighborhoodIterObject

Структура C, соответствующая объекту PyArrayNeighborhoodIter_Type — это PyArrayNeighborhoodIterObject.

PyArrayFlags_Type

Типы скалярных массивов

Для каждого из встроенных типов данных, которые могут присутствовать в массиве, существует тип Python. Большинство из них являются простыми оболочками соответствующего типа данных в C. Имена типов в C — это Py{TYPE}ArrType_Type , где {TYPE} может быть

Bool, Byte, Short, Int, Long, LongLong, UByte, UShort, UInt, ULong, ULongLong, Half, Float, Double, LongDouble, CFloat, CDouble, CLongDouble, String, Unicode, Void и Object.

Эти имена типов являются частью C-API и поэтому могут быть созданы в коде расширения C. Также есть PyIntpArrType_Type и PyUIntpArrType_Type, которые являются простыми заменителями одного из целочисленных типов, который может содержать указатель на платформе. Структура этих скалярных объектов не раскрывается коду C. Функция PyArray_ScalarAsCtype (..) может использоваться для извлечения значения типа C из скаляра массива, а функция PyArray_Scalar (...) может использоваться для построения скаляра массива из значения C.

Другие структуры C

Несколько новых структур C оказались полезными при разработке NumPy. Эти структуры C используются как минимум в одном вызове C-API и поэтому документированы здесь. Основная причина определения этих структур — упрощение использования Python ParseTuple C-API для преобразования из объектов Python в полезный объект C.

PyArray_Dims

PyArray_Dims

Эта структура очень полезна, когда требуется интерпретация информации о форме и/или шагах. Структура:

typedef struct {
    npy_intp *ptr;
    int len;
} PyArray_Dims;

Члены этой структуры:

npy_intp *PyArray_Dims.ptr

Указатель на список (npy_intp) целых чисел, которые обычно представляют форму массива или шаги массива.

int PyArray_Dims.len

Длина списка целых чисел. Предполагается, что доступ к ptr [0] до ptr [len-1] безопасен.

PyArray_Chunk

PyArray_Chunk

Это эквивалентно структуре объекта буфера в Python до члена ptr. На 32-битных платформах (т.е. если NPY_SIZEOF_INT == NPY_SIZEOF_INTP), член len также соответствует эквивалентному члену объекта буфера. Он полезен для представления общего односегментного блока памяти.

typedef struct {
    PyObject_HEAD
    PyObject *base;
    void *ptr;
    npy_intp len;
    int flags;
} PyArray_Chunk;

Члены:

PyObject *PyArray_Chunk.base

Объект Python, из которого происходит этот блок памяти. Необходимо, чтобы память учитывалась должным образом.

void *PyArray_Chunk.ptr

Указатель на начало односегментного блока памяти.

npy_intp PyArray_Chunk.len

Длина сегмента в байтах.

int PyArray_Chunk.flags

Любые флаги данных (например, NPY_ARRAY_WRITEABLE ), которые должны использоваться для интерпретации памяти.

PyArrayInterface

См. также

Интерфейс массивов

PyArrayInterface

Структура PyArrayInterface определена для того, чтобы модули NumPy и другие расширяющие модули могли использовать протокол быстрого интерфейса массивов. Метод __array_struct__ объекта, поддерживающего протокол быстрого интерфейса массивов, должен возвращать PyCObject , содержащий указатель на структуру PyArrayInterface с соответствующими деталями массива. После создания нового массива атрибут должен быть DECREF , что освободит структуру PyArrayInterface. Не забудьте INCREF объект (чей атрибут __array_struct__ был получен) и укажите член base нового PyArrayObject на этот же объект. Таким образом память для массива будет управляться правильно.

typedef struct {
    int two;
    int nd;
    char typekind;
    int itemsize;
    int flags;
    npy_intp *shape;
    npy_intp *strides;
    void *data;
    PyObject *descr;
} PyArrayInterface;
int PyArrayInterface.two

целое число 2 в качестве проверки на корректность.

int PyArrayInterface.nd

количество измерений в массиве.

char PyArrayInterface.typekind

Символ, указывающий на тип массива в соответствии с соглашением о типах: ‘t’ -> битовое поле, ‘b’ -> булево, ‘i’ -> целое со знаком, ‘u’ -> целое без знака, ‘f’ -> с плавающей точкой, ‘c’ -> комплексное с плавающей точкой, ‘O’ -> объект, ‘S’ -> (байтовый) строка, ‘U’ -> Юникод, ‘V’ -> пустое.

int PyArrayInterface.itemsize

Количество байтов, занимаемых каждым элементом в массиве.

int PyArrayInterface.flags

Любой из битов NPY_ARRAY_C_CONTIGUOUS (1), NPY_ARRAY_F_CONTIGUOUS (2), NPY_ARRAY_ALIGNED (0x100), NPY_ARRAY_NOTSWAPPED (0x200), или NPY_ARRAY_WRITEABLE (0x400) для указания информации о данных. Флаги NPY_ARRAY_ALIGNED, NPY_ARRAY_C_CONTIGUOUS и NPY_ARRAY_F_CONTIGUOUS могут быть фактически определены из других параметров. Флаг NPY_ARR_HAS_DESCR (0x800) также может быть установлен для указания объектам, потребляющим интерфейс массива версии 3, что член descr структуры присутствует (он будет проигнорирован объектами, потребляющими интерфейс массива версии 2).

npy_intp *PyArrayInterface.shape

Массив, содержащий размер массива в каждом измерении.

npy_intp *PyArrayInterface.strides

Массив, содержащий количество байтов, которые нужно пропустить, чтобы перейти к следующему элементу в каждом измерении.

void *PyArrayInterface.data

Указатель на первый элемент массива.

PyObject *PyArrayInterface.descr

Объект Python, описывающий тип данных более подробно (такой же, как ключ descr в __array_interface__). Это поле может быть NULL , если typekind и itemsize предоставляют достаточную информацию. Это поле также игнорируется, если флаг ARR_HAS_DESCR установлен в flags.

Внутренние структуры

Внутренне код использует некоторые дополнительные объекты Python, предназначенные в первую очередь для управления памятью. Эти типы недоступны напрямую из Python и не экспонируются в C-API. Они включены здесь только для полноты и помощи в понимании кода.

PyUFuncLoopObject

Условный оболочка C-структуры, содержащей информацию, необходимую для циклических операций. Это полезно, если вы пытаетесь понять код циклов ufunc. PyUFuncLoopObject — это соответствующая C-структура. Она определена в заголовке ufuncobject.h.

PyUFuncReduceObject

Условная оболочка C-структуры, содержащей информацию, необходимую для методов типа reduce для ufunc. Это полезно, если вы пытаетесь понять код reduce, accumulate и reduce-at. PyUFuncReduceObject — это соответствующая C-структура. Она определена в заголовке ufuncobject.h.

PyUFunc_Loop1d

Простая связанная цепочка C-структур, содержащих информацию, необходимую для определения цикла 1-d для ufunc для каждой определенной подписи пользовательского типа данных.

© 2008–2016 NumPy Developers
Licensed under the NumPy License.
https://docs.scipy.org/doc/numpy-1.10.1/reference/c-api.types-and-structures.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API