Типы Python и C-структуры
В коде C определено несколько новых типов. Большинство из них доступны из Python, но некоторые не экспонируются из-за ограниченного использования. Каждый новый тип Python имеет связанную с ним PyObject * с внутренней структурой, которая включает указатель на «таблицу методов», определяющую, как новое объекту ведет себя в Python. При получении объекта Python в код C вы всегда получаете указатель на структуру PyObject. Поскольку структура PyObject очень общая и определяет только PyObject_HEAD, сама по себе она не очень интересна. Однако разные объекты содержат больше деталей после PyObject_HEAD (но вы должны выполнить приведение к правильному типу, чтобы получить к ним доступ — или использовать функции-аксессоры или макросы).
Определенные новые типы Python
Типы Python — это функциональный эквивалент классов в Python в C. Создавая новый тип Python, вы делаете доступным новый объект для Python. Объект ndarray является примером нового типа, определенного в C. Новые типы определяются в C двумя основными шагами:
- создание C-структуры (обычно с именем
Py{Name}Object), которая бинарно совместима со структуройPyObject, но содержит дополнительную информацию, необходимую для этого конкретного объекта; - заполнение таблицы
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 -
Структура
PyArrayObjectC содержит всю необходимую информацию для массива. Все экземпляры 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
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 для элементов этого массива. Для встроенных типов он указывает на соответствующий скаляр массива. Для типов, определённых пользователем, он должен указывать на объект типа, определённого пользователем. Этот объект типа может либо наследоваться от скаляров массивов, либо нет. Если он не наследуется от скаляров массивов, то флаги
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), ‘=’ (native), ‘|’ (не важно, игнорировать). Все встроенные типы данных имеют порядок байтов ‘=’.
-
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 (необходим для массивов переменной длины). Возвращает 0 в случае успеха или -1 в случае неудачи. Требуется массив с соблюдением правил поведения.
-
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,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или 0-мерный массив, содержащий данные (если это необходимо для определения типа скаляра). Возвращаемое значение должно быть типа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на массивn_inбулевых значений и указатель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на непрерывный, корректный сегментm_middleцелочисленных индексов и указатель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
-
PyUFuncObject -
Ядро ufunc — это
PyUFuncObject, содержащее всю информацию, необходимую для вызова подлежащих C-кодовых циклов, которые выполняют фактическую работу. Он имеет следующую структуру:typedef struct { PyObject_HEAD int nin; int nout; int nargs; int identity; PyUFuncGenericFunction *functions; void **data; int ntypes; int reserved1; 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илиPyUFunc_AllOnesдля указания тождества для этой операции. Используется только для вызова 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-мерные векторные циклы, или
NULLесли дополнительные данные не нужны. Этот C-массив должен иметь такой же размер (т.е. ntypes), как массив функций.NULLиспользуется, если дополнительные данные не нужны. Некоторые C-API вызовы для UFuncs просто представляют собой 1-мерные векторные циклы, которые используют эти дополнительные данные для получения указателя на фактическую вызываемую функцию.
-
int PyUFuncObject.ntypes -
Количество поддерживаемых типов данных для ufunc. Это число определяет, сколько различных 1-мерных циклов (встроенных типов данных) доступно.
-
char *PyUFuncObject.name -
Строковое имя для ufunc. Используется динамически для построения атрибута __doc__ ufuncs.
-
char *PyUFuncObject.types -
Массив из
8-битных номеров типов, который содержит сигнатуру типа для функции для каждого поддерживаемого (встроенного) типа данных. Для каждой из ntypes функций соответствующий набор чисел типов в этом массиве показывает, как аргумент args должен интерпретироваться в 1-мерном векторном цикле. Эти номера типов не обязательно должны быть одинаковыми, и поддерживаются ufuncs смешанных типов.
-
char *PyUFuncObject.doc -
Документация для ufunc. Не должна содержать сигнатуру функции, так как она генерируется динамически при получении __doc__.
-
void *PyUFuncObject.ptr -
Любая динамически выделенная память. В настоящее время используется для динамически созданных ufuncs из python-функций для хранения места для членов типов, данных и имен.
-
PyObject *PyUFuncObject.obj -
Для ufuncs, динамически созданных из python-функций, этот член содержит ссылку на базовую python-функцию.
-
PyObject *PyUFuncObject.userloops -
Словарь пользовательских 1-мерных векторных циклов (хранящихся как CObject ptr) для пользовательских типов. Пользователь может зарегистрировать цикл для любого пользовательского типа. Он извлекается по номеру типа. Номера типов пользователей всегда больше, чем
NPY_USERDEF.
-
npy_uint32 PyUFuncObject.op_flags -
Переопределить флаги операнда по умолчанию для каждого операнда ufunc.
-
npy_uint32 PyUFuncObject.iter_flags -
Переопределить флаги nditer по умолчанию для ufunc.
-
Тип PyArrayIter
-
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 -
где
— число измерений в базовом массиве.
-
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] * dims_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} может быть
Эти имена типов являются частью 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‘d, что освободит структуруPyArrayInterface. Не забудьтеINCREFобъект (чей атрибут__array_struct__был извлечен) и укажите базовый член нового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-like ufuncs. Это полезно, если вы пытаетесь понять код reduce, accumulate и reduce-at. Структура
PyUFuncReduceObject— это соответствующая структура C. Она определена в заголовочном файлеufuncobject.h.
-
PyUFunc_Loop1d -
Простая связанный список C-структур, содержащих информацию, необходимую для определения цикла 1-d для ufunc для каждой определенной сигнатуры пользовательского типа данных.
© 2008–2017 NumPy Developers
Licensed under the NumPy License.
https://docs.scipy.org/doc/numpy-1.12.0/reference/c-api.types-and-structures.html