陣列 API#

一流智力的考驗,是在於能否在腦中同時持有兩種
相反的想法,並仍然保持
運作能力。
F. Scott Fitzgerald
對於成功的技術而言,現實必須優先於公關,
因為自然是無法被愚弄的。
Richard P. Feynman

陣列結構與資料存取#

這些巨集存取 PyArrayObject 結構成員,並且定義於 ndarraytypes.h 中。輸入引數 arr 可以是任何可直接解譯為 PyArrayObject*PyObject* (任何 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 版本新增功能。

將 dtype 為 descr 的記憶體位置 item 設定為 value

此函數等同於使用 Python 賦值設定單一陣列元素。成功時傳回 0,失敗時傳回 -1 並設定錯誤。

注意

如果 descr 已設定 NPY_NEEDS_INIT 旗標,則資料必須有效或記憶體必須歸零。

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

轉換 obj 並將其放置在 itemptr 指向的 ndarray arr 中的位置。如果發生錯誤則傳回 -1,成功則傳回 0。

注意

一般而言,處理任意 Python 物件時,建議優先使用 PyArray_Pack。例如,Setitem 無法處理不同 dtype 之間的任意轉換。

void PyArray_ENABLEFLAGS(PyArrayObject *arr, int flags)#

啟用指定的陣列旗標。此函數不執行驗證,並假設您知道自己在做什麼。

void PyArray_CLEARFLAGS(PyArrayObject *arr, int flags)#

清除指定的陣列旗標。此函數不執行驗證,並假設您知道自己在做什麼。

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

這兩個巨集相似,並且取得陣列的資料緩衝區的指標。第一個巨集可以 (而且應該) 指派給特定的指標,而第二個巨集則用於通用處理。如果您沒有保證陣列是連續和/或對齊的,請務必了解如何存取陣列中的資料,以避免記憶體和/或對齊問題。

npy_intp *PyArray_DIMS(PyArrayObject *arr)#

傳回陣列的維度/形狀的指標。元素的數量與陣列的維度數量相符。對於 0 維陣列可以傳回 NULL

npy_intp *PyArray_SHAPE(PyArrayObject *arr)#

PyArray_DIMS 的同義詞,命名是為了與 Python 中 shape 的用法一致。

npy_intp *PyArray_STRIDES(PyArrayObject *arr)#

傳回陣列步幅的指標。元素的數量與陣列的維度數量相符。

npy_intp PyArray_DIM(PyArrayObject *arr, int n)#

傳回第 n \(^{\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_SIZE (obj) 的更安全版本。

npy_intp PyArray_NBYTES(PyArrayObject *arr)#

傳回陣列消耗的總位元組數。

PyObject *PyArray_BASE(PyArrayObject *arr)#

這會傳回陣列的基礎物件。在大多數情況下,這表示擁有陣列所指向記憶體的物件。

如果您使用 C API 建構陣列,並指定您自己的記憶體,則應使用函數 PyArray_SetBaseObject 將基礎設定為擁有記憶體的物件。

如果已設定 NPY_ARRAY_WRITEBACKIFCOPY 旗標,則它具有不同的含義,也就是基礎是目前的陣列在複製解析時將複製到其中的陣列。NumPy 未來版本可能會變更此基礎屬性對於兩個函數的重載。

PyArray_Descr *PyArray_DESCR(PyArrayObject *arr)#

傳回陣列 dtype 屬性的借用參考。

PyArray_Descr *PyArray_DTYPE(PyArrayObject *arr)#

是 PyArray_DESCR 的同義詞,命名是為了與 Python 中 ‘dtype’ 的用法一致。

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

從 itemptr 指向的位置的 ndarray arr 中取得內建型別的 Python 物件。失敗時傳回 NULL

numpy.ndarray.item 與 PyArray_GETITEM 相同。

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

PyCapsule __array_finalize__ 指向的函數。第一個引數是新建立的子型別。第二個引數 (如果不是 NULL) 是「父」陣列 (如果陣列是使用切片或其他存在可清楚區分的父項的操作建立的)。此常式可以執行任何它想做的事情。它應在發生錯誤時傳回 -1,否則傳回 0。

資料存取#

這些函數和巨集提供從 C 輕鬆存取 ndarray 元素的方式。這些適用於所有陣列。但是,當存取陣列中的資料時,如果資料不是機器位元組順序、未對齊或不可寫入,您可能需要小心。換句話說,除非您知道自己在做什麼,或者先前已使用 PyArray_FromAny 保證了可寫入、對齊且為機器位元組順序的陣列,否則請務必遵守旗標的狀態。如果您希望處理所有型別的陣列,則每種類型的 copyswap 函數對於處理行為不端的陣列很有用。某些平台 (例如 Solaris) 不喜歡未對齊的資料,如果您取消參考未對齊的指標,則會當機。其他平台 (例如 x86 Linux) 使用未對齊的資料只會執行得更慢。

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

傳回 ndarray aobj 在由 c 陣列 ind 給定的 N 維索引 (其大小必須至少為 aobj ->nd) 處的資料指標。您可能會想要將傳回的指標型別轉換為 ndarray 的資料型別。

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

快速、內嵌存取 ndarray obj 中給定座標的元素,該 ndarray 必須分別具有 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 樣式連續(flags 對於 data = NULL 為非零,或者 flags & NPY_ARRAY_F_CONTIGUOUS 對於非 NULL data 為非零)。任何提供的 dimsstrides 都會複製到新陣列物件新配置的維度和步幅陣列中。

PyArray_CheckStrides 可以幫助驗證非 NULL 步幅資訊。

如果提供 data,則它必須在陣列的生命週期內保持有效。管理此問題的一種方法是透過 PyArray_SetBaseObject

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

如果 descr 不是 NULL,此函式會盜用對 descr 的參考。此陣列建立常式允許方便地建立符合現有陣列形狀和記憶體佈局的新陣列,並可能變更佈局和/或資料型別。

orderNPY_ANYORDER 時,如果 prototype 是 Fortran 陣列,則結果順序為 NPY_FORTRANORDER,否則為 NPY_CORDER。當 orderNPY_KEEPORDER 時,即使 prototype 的軸未採用 C 或 Fortran 順序,結果順序也會與 prototype 的順序相符。

如果 descr 為 NULL,則會使用 prototype 的資料型別。

如果 subok 為 1,則新建立的陣列將使用 prototype 的子型別來建立新陣列,否則將建立基礎類別陣列。

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

這與 PyArray_NewFromDescr (….) 類似,不同之處在於您使用 type_numitemsize 指定資料型別描述器,其中 type_num 對應於內建(或使用者定義)型別。如果型別始終具有相同的位元組數,則會忽略 itemsize。否則,itemsize 會指定此陣列的特定大小。

警告

如果將資料傳遞至 PyArray_NewFromDescrPyArray_New,則在刪除新陣列之前,不得取消配置此記憶體。如果此資料來自另一個 Python 物件,則可以使用 Py_INCREF 增加該物件的參考計數,並設定新陣列的 base 成員以指向該物件來完成此操作。如果傳入步幅,則它們必須與陣列的維度、itemsize 和資料一致。

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

建立一個新的未初始化陣列,其型別為 typenum,其在 nd 維度中的大小由整數陣列 dims 給定。陣列的記憶體是未初始化的(除非 typenum 是 NPY_OBJECT,在這種情況下,陣列中的每個元素都會設定為 NULL)。typenum 參數允許指定任何內建資料型別,例如 NPY_FLOATNPY_LONG。如果需要,可以使用 PyArray_FILLWBYTE (return_object, 0) 將陣列的記憶體設定為零。此函式不能用於建立彈性型別陣列(未給定 itemsize)。

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

圍繞給定指標指向的 data 建立陣列包裝器。陣列旗標將具有預設值,即資料區域運作良好且為 C 樣式連續。陣列的形狀由長度為 nddims c 陣列給定。陣列的資料型別由 typenum 指示。如果資料來自另一個參考計數的 Python 物件,則在傳入指標後,應增加此物件的參考計數,並且傳回的 ndarray 的 base 成員應指向擁有資料的 Python 物件。這將確保在傳回的陣列存在期間,提供的記憶體不會被釋放。

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

此函式會盜用對 descr 的參考。

使用提供的資料型別描述器 descr 建立新陣列,其形狀由 nddims 決定。

void PyArray_FILLWBYTE(PyObject *obj, int val)#

val 的內容(評估為位元組)填滿 obj 指向的陣列 — 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)#

此函式**盜用對** obj **的參考**,並將其設定為 arr 的 base 屬性。

如果您透過傳入自己的記憶體緩衝區作為參數來建構陣列,則需要設定陣列的 base 屬性,以確保記憶體緩衝區的生命週期是適當的。

傳回值在成功時為 0,失敗時為 -1。

如果提供的物件是陣列,此函式會遍歷 base 指標的鏈,以便每個陣列都直接指向記憶體的擁有者。一旦設定 base,就不得將其變更為另一個值。

從其他物件#

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

這是用於從任何巢狀序列或公開陣列介面的物件 op 取得陣列的主要函式。參數允許指定所需的 dtype、可接受的最小 (min_depth) 和最大 (max_depth) 維度數,以及陣列的其他 requirements。此函式**盜用對** dtype 參數**的參考**,該參數需要是 PyArray_Descr 結構,指示所需的資料型別(包括所需的位元組順序)。dtype 參數可能為 NULL,表示任何資料型別(和位元組順序)都是可接受的。除非 NPY_ARRAY_FORCECAST 存在於 flags 中,否則如果無法從物件安全地取得資料型別,則此呼叫將產生錯誤。如果您想要對 dtype 使用 NULL 並確保陣列未交換,請使用 PyArray_CheckFromAny。深度參數的任一值為 0 都會導致參數被忽略。可以新增以下任何陣列旗標(例如,使用 |)以取得 requirements 參數。如果您的程式碼可以處理一般陣列(例如,跨步、位元組交換或未對齊的陣列),則 requirements 可能為 0。此外,如果 op 尚不是陣列(或未公開陣列介面),則會建立新陣列(並使用序列協定從 op 填滿)。新陣列將具有 NPY_ARRAY_DEFAULT 作為其旗標成員。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,後者表示陣列應對齊,使得 strides 是元素大小的倍數。

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

op 已經是一個陣列,但需要是特定的 newtype (包括位元組順序) 或具有某些 requirements 時,PyArray_FromAny 的特殊情況。

PyObject *PyArray_FromStructInterface(PyObject *op)#

從一個 Python 物件返回一個 ndarray 物件,該物件公開了 __array_struct__ 屬性並遵循陣列介面協定。如果該物件不包含此屬性,則返回對 Py_NotImplemented 的借用參考。

PyObject *PyArray_FromInterface(PyObject *op)#

從一個 Python 物件返回一個 ndarray 物件,該物件公開了 __array_interface__ 屬性並遵循陣列介面協定。如果該物件不包含此屬性,則返回對 Py_NotImplemented 的借用參考。

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

從一個 Python 物件返回一個 ndarray 物件,該物件公開了 __array__ 方法。 __array__ 的第三方實作必須接受 dtypecopy 關鍵字參數。 context 未使用。

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

此函數從任何巢狀序列或陣列介面匯出物件 *op* 返回一個 (C 風格) 連續且行為良好的函數陣列,該陣列的 (非彈性) 類型由枚舉的 *typenum* 給定,最小深度為 *min_depth*,最大深度為 *max_depth*。 等效於呼叫 PyArray_FromAny,其中 requirements 設置為 NPY_ARRAY_DEFAULT,並且 type 參數的 type_num 成員設置為 *typenum*。

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

此函數從任何巢狀序列或陣列介面匯出物件返回一個行為良好的 C 風格連續陣列。 陣列可以擁有的最小維度數由 min_depth 給出,而最大維度數為 max_depth。 這等效於呼叫 PyArray_FromAny,其中 requirements 為 NPY_ARRAY_DEFAULTNPY_ARRAY_ENSUREARRAY

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

從任何巢狀序列或陣列介面匯出物件 op 返回一個對齊且為本機位元組順序的陣列,其類型由枚舉的 typenum 給定。 陣列可以擁有的最小維度數由 min_depth 給出,而最大維度數為 max_depth。 這等效於呼叫 PyArray_FromAny,其中 requirements 設置為 BEHAVED。

PyObject *PyArray_EnsureArray(PyObject *op)#

此函數竊取了對 op **的參考**,並確保 op 是一個基底類別 ndarray。 它特殊處理陣列純量,但其他情況下會呼叫 PyArray_FromAny (op, 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 構造一個單一類型的一維 ndarray,該物件導出 (單段) 緩衝區協議 (或具有返回導出緩衝區協議的物件的 __buffer__ 屬性)。 將首先嘗試可寫入的緩衝區,然後嘗試唯讀緩衝區。 返回陣列的 NPY_ARRAY_WRITEABLE 標誌將反映哪個緩衝區成功。 數據假定從物件的內存位置開始的 offset 字節處開始。 緩衝區中數據的類型將根據數據類型描述符 dtype 進行解釋。 如果 count 為負數,則將根據緩衝區的大小和請求的 itemsize 確定,否則,count 表示應從緩衝區轉換多少個元素。

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

從源陣列 src 複製到目標陣列 dest 中,必要時執行數據類型轉換。 如果發生錯誤,則返回 -1 (否則為 0)。 src 的形狀必須可廣播到 dest 的形狀。 NumPy 在複製兩個陣列時檢查重疊的內存。

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

根據陣列強制轉換規則,將物件 src 賦值給 NumPy 陣列 dest。 這基本上與 PyArray_FromAny 相同,但直接賦值給輸出陣列。 成功時返回 0,失敗時返回 -1。

PyArrayObject *PyArray_GETCONTIGUOUS(PyObject *op)#

如果 op 已經是 (C 風格) 連續且行為良好,則只需返回參考,否則返回陣列的 (連續且行為良好) 副本。 參數 op 必須是 (ndarray 的子類別),並且不執行檢查。

PyObject *PyArray_FROM_O(PyObject *obj)#

obj 轉換為 ndarray。 參數可以是任何巢狀序列或導出陣列介面的物件。 這是 PyArray_FromAny 的宏形式,對其他參數使用 NULL, 0, 0, 0。 您的程式碼必須能夠處理任何數據類型描述符和數據標誌的任何組合才能使用此宏。

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

PyArray_FROM_O 類似,但它可以接受 *requirements* 的參數,指示結果陣列必須具有的屬性。 可以強制執行的可用 requirements 為 NPY_ARRAY_C_CONTIGUOUS, NPY_ARRAY_F_CONTIGUOUS, NPY_ARRAY_ALIGNED, NPY_ARRAY_WRITEABLE, NPY_ARRAY_NOTSWAPPED, NPY_ARRAY_ENSURECOPY, NPY_ARRAY_WRITEBACKIFCOPY, NPY_ARRAY_FORCECASTNPY_ARRAY_ENSUREARRAY。 也可以使用標誌的標準組合

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

PyArray_FROM_O 類似,但它可以接受 *typenum* 的參數,指定返回陣列的類型編號。

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

PyArray_FROM_OFPyArray_FROM_OT 的組合,允許同時提供 *typenum* 和 *flags* 參數。

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

PyArray_FromAny 類似,但數據類型是使用類型編號指定的。 PyArray_DescrFromType(*typenum*) 直接傳遞給 PyArray_FromAny。 如果將 NPY_ARRAY_ENSURECOPY 作為 requirements 傳遞,則此宏還會將 NPY_ARRAY_DEFAULT 添加到 requirements 中。

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

封裝函數和方法的功能,這些函數和方法接受 axis= 關鍵字,並在使用 None 作為 axis 參數時正常工作。 輸入陣列為 obj,而 *axis 是一個轉換後的整數 (因此 *axis == NPY_RAVEL_AXIS 是 None 值),並且 requirements 給出了 obj 所需的屬性。 輸出是輸入的轉換版本,以便滿足 requirements,並且在需要時發生展平。 在輸出時,*axis 的負值會被轉換,並檢查新值以確保與 obj 的形狀一致。

處理類型#

Python 類型的通用檢查#

int PyArray_Check(PyObject *op)#

如果 op 是 Python 物件,且其型別為 PyArray_Type 的子型別,則評估為真。

int PyArray_CheckExact(PyObject *op)#

如果 op 是 Python 物件,且其型別為 PyArray_Type,則評估為真。

int PyArray_HasArrayInterface(PyObject *op)#

如果 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 的子型別的實例),或是 PyArray_Type(或其子類別)的實例且維度為 0,則評估為真。

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 的子型別的實例)或是 PyArray_Type 子型別的實例且維度為 0,則評估為真。

資料型別存取器#

某些描述器屬性可能不一定總是已定義,且不應或無法直接存取。

變更版本 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 的 Metadata,可以是 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-metadata 物件。 通常不需要此存取器。 C-Metadata 欄位確實提供對 datetime/timedelta 時間單位資訊的存取權。

PyArray_ArrayDescr *PyDataType_SUBARRAY(PyArray_Descr *descr)#

關於子陣列 dtype 的資訊,相當於 Python 的 np.dtype.basenp.dtype.shape

如果此值不是 NULL,則此資料型別描述器是另一個資料型別描述器的 C 樣式連續陣列。 換句話說,此描述器描述的每個元素實際上是某個其他基礎描述器的陣列。 這作為另一個資料型別描述器中欄位的資料型別描述器最有用。 如果此值不是 NULL,則 fields 成員應為 NULL(但基礎描述器的 fields 成員可能不是 NULL)。

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

基礎型別的資料型別描述器物件。

PyObject *shape#

子陣列的形狀(始終為 C 樣式連續),以 Python 元組表示。

資料型別檢查#

對於 typenum 巨集,引數是表示列舉陣列資料型別的整數。 對於陣列型別檢查巨集,引數必須是 PyObject*,可以直接解譯為 PyArrayObject*

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

型別表示無號整數。

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

型別表示有號整數。

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

型別表示任何整數。

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

型別表示任何浮點數。

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

型別表示任何複數浮點數。

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

型別表示任何整數、浮點數或複數浮點數。

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

型別表示字串資料型別。

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

型別表示彈性陣列型別之一( NPY_STRINGNPY_UNICODENPY_VOID )。

int PyDataType_ISUNSIZED(PyArray_Descr *descr)#

型別沒有附加大小資訊,且可以調整大小。 應僅在彈性 dtype 上呼叫。 附加到陣列的型別將始終調整大小,因此此巨集的陣列形式不存在。

對於沒有欄位的結構化資料型別,此函式現在傳回 False。

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

型別表示使用者定義型別。

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

型別為彈性或使用者定義。

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

型別表示物件資料型別。

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

類型代表布林資料類型。

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

類型具有與其關聯的欄位。

int PyArray_ISNOTSWAPPED(PyArrayObject *m)#

如果 ndarray m 的資料區域根據陣列的資料類型描述符,是以機器位元組順序排列,則評估為 true。

int PyArray_ISBYTESWAPPED(PyArrayObject *m)#

如果 ndarray m 的資料區域根據陣列的資料類型描述符,不是以機器位元組順序排列,則評估為 true。

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

如果位元組順序字元 b1b2 ( NPY_LITTLENPY_BIGNPY_NATIVENPY_IGNORE ) 相等,或者在它們的原生位元組順序規範中是等效的,則為 True。因此,在小端機器上,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 位元浮點數值可能會在大整數上遺失精確度,但仍允許這樣做,以便在沒有明確要求的情況下,不會擴散使用 long double。彈性陣列類型不會根據其長度使用此函數進行檢查。

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

PyArray_CanCastTypeTo 在 NumPy 1.6 及更高版本中取代了此函數。

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

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

如果資料類型為 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)#

如果可以根據 casting 中給定的轉換規則將 arr 轉換為 totype,則返回非零值。如果 arr 是陣列純量,則會考慮其值,並且當值在轉換為較小類型時不會溢位或被截斷為整數時,也會返回非零值。

PyArray_Descr *PyArray_MinScalarType(PyArrayObject *arr)#

注意

隨著 NumPy 2 中 NEP 50 的採用,此函數在內部不再使用。目前提供此函數是為了向後相容性,但預計最終將被棄用。

如果 arr 是陣列,則返回其資料類型描述符,但如果 arr 是陣列純量(維度為 0),則它會找到可以將值轉換為的最小尺寸的資料類型,而不會溢位或截斷為整數。

此函數不會將複數降級為浮點數,也不會將任何類型降級為布林值,但當純量值為正數時,會將帶符號整數降級為無符號整數。

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

尋找可以安全轉換 type1type2 的最小尺寸和種類的資料類型。此函數是對稱且結合律的。字串或 unicode 結果將是適當的大小,用於儲存轉換為字串或 unicode 的輸入類型的最大值。

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

這會將類型提升應用於所有輸入陣列和 dtype 物件,使用 NumPy 規則來組合純量和陣列,以確定具有給定運算元集合的運算的輸出類型。這與 ufuncs 產生的結果類型相同。

有關類型提升演算法的更多詳細資訊,請參閱 numpy.result_type 的文件。

int PyArray_ObjectType(PyObject *op, int mintype)#

此函數已被 PyArray_ResultType 取代。

此函數可用於確定兩個或多個陣列可以轉換為的通用類型。它僅適用於非彈性陣列類型,因為未傳遞 itemsize 資訊。mintype 參數代表最小可接受類型,而 op 代表將轉換為陣列的物件。返回值是列舉的類型編號,代表 op 應該具有的資料類型。

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

此函數提供的功能在很大程度上已被 1.6 中引入的迭代器 NpyIter 取代,並帶有旗標 NPY_ITER_COMMON_DTYPE 或所有運算元使用相同的 dtype 參數。

op 中包含的 Python 物件序列轉換為 ndarray 陣列,每個陣列都具有相同的資料類型。類型的選擇方式與 PyArray_ResultType 相同。序列的長度在 n 中返回,並且 n 長度的 PyArrayObject 指標陣列是返回值(如果發生錯誤,則為 NULL)。返回的陣列必須由此常式的調用者釋放(使用 PyDataMem_FREE ),並且其中的所有陣列物件都必須 DECREF ,否則會發生記憶體洩漏。下面的範例範本程式碼顯示了典型的用法

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

指向新建立的記憶體的指標,其大小為 arr ->itemsize,其中保存該類型的 0 表示。當不再需要返回的指標 ret 時,必須使用 PyDataMem_FREE (ret) 釋放。

char *PyArray_One(PyArrayObject *arr)#

指向新建立的記憶體的指標,其大小為 arr ->itemsize,其中保存該類型的 1 表示。當不再需要返回的指標 ret 時,必須使用 PyDataMem_FREE (ret) 釋放。

int PyArray_ValidType(int typenum)#

如果 typenum 代表有效的類型編號(內建或使用者定義或字元代碼),則返回 NPY_TRUE。否則,此函數返回 NPY_FALSE

使用者定義的資料類型#

void PyArray_InitArrFuncs(PyArray_ArrFuncs *f)#

將所有函數指標和成員初始化為 NULL

int PyArray_RegisterDataType(PyArray_DescrProto *dtype)#

注意

從 NumPy 2.0 開始,此 API 被視為舊版,新的 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 的所有物件執行 INCREF 的函數。如果 ptr 是一個結構化型別的開始,且在任何偏移量處都有物件,則這將(遞迴地)遞增結構化型別中所有類似物件項目的參考計數。

int PyArray_XDECREF(PyArrayObject *op)#

用於包含任何 Python 物件的陣列 op。它根據 op 的資料型別,遞減陣列中每個物件的參考計數。正常回傳值為 0。如果發生錯誤,則回傳 -1。

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

一個根據資料型別 dtype,對位置 ptr 的所有類似物件項目執行 XDECREF 的函數。這是遞迴運作的,因此如果 dtype 本身具有包含類似物件項目的資料型別的欄位,則所有類似物件的欄位都將被 XDECREF 'd

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

前提條件:arrbase 的副本(儘管可能具有不同的 strides、ordering 等)。設定 NPY_ARRAY_WRITEBACKIFCOPY 旗標和 arr->base,並將 base 設定為 READONLY。在呼叫 Py_DECREF 之前,呼叫 PyArray_ResolveWritebackIfCopy,以便將任何變更複製回 base 並重設 READONLY 旗標。

成功時回傳 0,失敗時回傳 -1。

陣列旗標#

PyArrayObject 結構的 flags 屬性包含關於陣列使用的記憶體(由 data 成員指向)的重要資訊。此旗標資訊必須保持準確,否則可能會導致奇怪的結果甚至區段錯誤。

有 6 個(二進制)旗標描述資料緩衝區使用的記憶體區域。這些常數在 arrayobject.h 中定義,並決定旗標的位元位置。Python 公開了一個友好的基於屬性的介面以及類似字典的介面,用於取得(以及在適當情況下,設定)這些旗標。

各種記憶體區域都可以由 ndarray 指向,因此需要這些旗標。如果您在 C 程式碼中取得任意的 PyArrayObject,您需要注意已設定的旗標。如果您需要保證某種類型的陣列(例如 NPY_ARRAY_C_CONTIGUOUSNPY_ARRAY_BEHAVED),則將這些要求傳遞到 PyArray_FromAny 函數中。

在 NumPy 1.6 和更早版本中,以下旗標沒有 _ARRAY_ 巨集命名空間。常數名稱的該形式在 1.7 中已棄用。

基本陣列旗標#

ndarray 可以具有一個資料段,該資料段不是您可以操作的行為良好的記憶體的簡單連續區塊。它可能未與字組邊界對齊(在某些平台上非常重要)。它的資料可能具有與機器識別的不同的位元組順序。它可能不可寫入。它可能採用 Fortran 連續順序。陣列旗標用於指示可以說明與陣列關聯的資料的內容。

NPY_ARRAY_C_CONTIGUOUS#

資料區域採用 C 風格的連續順序(最後一個索引變化最快)。

NPY_ARRAY_F_CONTIGUOUS#

資料區域採用 Fortran 風格的連續順序(第一個索引變化最快)。

注意

陣列可以同時是 C 風格和 Fortran 風格的連續。對於一維陣列來說,這是很明顯的,但對於更高維度的陣列來說也可能是如此。

即使對於連續陣列,給定維度的步幅 arr.strides[dim] 也可能是任意的,如果 arr.shape[dim] == 1 或陣列沒有元素。通常情況下,對於 C 風格的連續陣列,self.strides[-1] == self.itemsize 或對於 Fortran 風格的連續陣列,self.strides[0] == self.itemsize 並不成立。從 C API 存取陣列的 itemsize 的正確方法是 PyArray_ITEMSIZE(arr)

NPY_ARRAY_OWNDATA#

資料區域由此陣列擁有。永遠不應手動設定,而是建立一個包裝資料的 PyObject,並將陣列的 base 設定為該物件。有關範例,請參閱 test_mem_policy 中的測試。

NPY_ARRAY_ALIGNED#

資料區域和所有陣列元素都適當地對齊。

NPY_ARRAY_WRITEABLE#

資料區域可以寫入。

請注意,以上 3 個旗標的定義方式是,新的、行為良好的陣列會將這些旗標定義為 true。

NPY_ARRAY_WRITEBACKIFCOPY#

資料區域表示一個(行為良好的)副本,當呼叫 PyArray_ResolveWritebackIfCopy 時,其資訊應傳輸回原始物件。

這是一個特殊旗標,如果此陣列表示由於使用者在 PyArray_FromAny 中需要特定旗標而建立的副本,並且必須建立某個其他陣列的副本(並且使用者要求在這種情況下設定此旗標),則會設定此旗標。然後,base 屬性指向「行為不端」的陣列(已設定為唯讀)。PyArray_ResolveWritebackIfCopy 將其內容複製回「行為不端」的陣列(如有必要,會進行轉換),並將「行為不端」的陣列重設為 NPY_ARRAY_WRITEABLE。如果「行為不端」的陣列一開始就不是 NPY_ARRAY_WRITEABLE,則 PyArray_FromAny 將會回傳錯誤,因為 NPY_ARRAY_WRITEBACKIFCOPY 將不可能。

PyArray_UpdateFlags (obj, flags) 將更新 obj->flagsflags,它可以是 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 風格連續的,則評估為 true。

int PyArray_IS_F_CONTIGUOUS(PyObject *arr)#

如果 arr 是 Fortran 風格連續的,則評估為 true。

int PyArray_ISFORTRAN(PyObject *arr)#

如果 arr 是 Fortran 風格連續且不是 C 風格連續的,則評估為 true。PyArray_IS_F_CONTIGUOUS 是測試 Fortran 風格連續性的正確方法。

int PyArray_ISWRITEABLE(PyObject *arr)#

如果 arr 的資料區域可以寫入,則評估為 true

int PyArray_ISALIGNED(PyObject *arr)#

如果 arr 的資料區域在機器上正確對齊,則評估為 true。

int PyArray_ISBEHAVED(PyObject *arr)#

如果 arr 的資料區域已對齊且可寫入,並且根據其描述符採用機器位元組順序,則評估為 true。

int PyArray_ISBEHAVED_RO(PyObject *arr)#

評估 arr 的資料區域是否對齊且為機器位元組順序。

int PyArray_ISCARRAY(PyObject *arr)#

評估 arr 的資料區域是否為 C 樣式連續,且 PyArray_ISBEHAVED (arr) 為真。

int PyArray_ISFARRAY(PyObject *arr)#

評估 arr 的資料區域是否為 Fortran 樣式連續,且 PyArray_ISBEHAVED (arr) 為真。

int PyArray_ISCARRAY_RO(PyObject *arr)#

評估 arr 的資料區域是否為 C 樣式連續、對齊且為機器位元組順序。

int PyArray_ISFARRAY_RO(PyObject *arr)#

評估 arr 的資料區域是否為 Fortran 樣式連續、對齊且為機器位元組順序

int PyArray_ISONESEGMENT(PyObject *arr)#

評估 arr 的資料區域是否由單一(C 樣式或 Fortran 樣式)連續區段組成。

void PyArray_UpdateFlags(PyArrayObject *arr, int flagmask)#

NPY_ARRAY_C_CONTIGUOUSNPY_ARRAY_ALIGNEDNPY_ARRAY_F_CONTIGUOUS 陣列旗標可以從陣列物件本身「計算」出來。此常式會執行所需的計算,以更新 flagmask 中指定的 arr 的一個或多個旗標。

警告

重要的是保持旗標更新(使用 PyArray_UpdateFlags 可以幫助),每當對陣列執行可能導致它們變更的操作時。NumPy 中稍後依賴這些旗標狀態的計算不會重複計算來更新它們。

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

如果 obj 是可寫入的,此函數不會執行任何操作並傳回 0。如果 obj 不可寫入,則會引發例外狀況並傳回 -1。它也可能執行其他內部管理,例如針對轉換為檢視的陣列發出警告。在寫入陣列之前,請務必在某些時候呼叫此函數。

name 是陣列的名稱,用於提供更好的錯誤訊息。它可以是「assignment destination」、「output array」或甚至是「array」之類的東西。

ArrayMethod API#

ArrayMethod 迴圈旨在作為一種通用機制,用於寫入陣列上的迴圈,包括 ufunc 迴圈和轉換。公共 API 在 numpy/dtype_api.h 標頭中定義。請參閱 PyArrayMethod_Context 和 PyArrayMethod_Spec 以取得 ArrayMethod API 中公開的 C 結構的文件。

插槽和 Typedefs#

這些用於識別 ArrayMethod 插槽實作哪種函數。請參閱下方 插槽和 Typedefs 以取得每個插槽必須實作的函數的文件。

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 中呼叫時未設定 outresolve_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]) 的符號。

  • 我們不使用 object 的身分,但針對空的 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 時在 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#

可以在執行階段變更的旗標。

Typedefs#

下方說明 ArrayMethod API 使用者可以實作的函數的 Typedefs。

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 是因為我們未來可能需要傳入 Interpreter 狀態或類似狀態,但我們不想傳入完整上下文(包含指向 dtype、方法、呼叫者的指標,這些對於遍歷函數都沒有意義)。我們目前假設此上下文可以在未來直接傳遞(對於結構化 dtype)。

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

簡化的 get_loop 函數,專用於 dtype 遍歷

它應設定遍歷迴圈所需的旗標,並將 out_loop 設定為迴圈函數,該函數必須是有效的 PyArrayMethod_TraverseLoop 指標。目前這用於將嵌入參考的陣列歸零和清除。

API 函數和 Typedefs#

這些函數是 NumPy 陣列主要 API 的一部分,並與 ArrayMethod API 的其餘部分一起新增。

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

直接從給定的 ArrayMethod 規範將迴圈新增至 ufunc。主要的 ufunc 註冊函數。這會將新的實作/迴圈新增至 ufunc。它取代了 PyUFunc_RegisterLoopForType

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

請注意,目前輸出 dtype 始終為 NULL,除非它們也是簽章的一部分。這是實作細節,未來可能會變更。但是,一般而言,promoter 不應需要輸出 dtype。為 ufunc 註冊新的 promoter。第一個引數是要註冊 promoter 的 ufunc。第二個引數是包含 DType 或 None 的 Python tuple,其符合 ufunc 的輸入和輸出數量。最後一個引數是 promoter,它是一個儲存在 PyCapsule 中的函數。它會傳遞運算和要求的 DType 簽章,並且可以變更它,以嘗試搜尋相符的迴圈/promoter。

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

promoter 函數的類型,必須包裝到名為 "numpy._ufunc_promoter"PyCapsule 中。它會傳遞運算和要求的 DType 簽章,並且可以變更簽章,以嘗試搜尋新的迴圈或 promoter,其可以透過將輸入轉換為「promoted」DType 來完成運算。

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

在執行浮點運算後,以考量透過 numpy.errstate 設定的錯誤訊號發送方式來檢查浮點錯誤。採用運算的名稱以用於錯誤訊息,以及一個整數旗標,該旗標是 NPY_FPE_DIVIDEBYZERONPY_FPE_OVERFLOWNPY_FPE_UNDERFLOWNPY_FPE_INVALID 其中之一,以指示要檢查哪個錯誤。

失敗時傳回 -1(已引發錯誤),成功時傳回 0。

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

允許在現有的 ufunc 迴圈周圍建立相當輕量的包裝函式。這個想法主要用於單位,因為目前它在某種程度上受到限制,因為它強制您不能使用來自另一個 ufunc 的迴圈。

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

此函數用於轉換給定的描述元(傳遞至 resolve_descriptors),並為包裝的迴圈翻譯它們。新的描述元必須可與舊的描述元檢視,必須支援 NULL(用於輸出引數),且通常應轉發。

此函數的輸出將用於建構引數的檢視,就像它們是翻譯後的 dtype 一樣,且不使用轉換。這表示此機制主要適用於「包裝」另一個 DType 實作的 DType。例如,單位 DType 可以使用此功能來包裝現有的浮點 DType,而無需重新實作低階 ufunc 邏輯。在單位範例中,resolve_descriptors 將處理從輸入單位計算輸出單位。

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

此函數用於將實際的迴圈描述元(由原始 resolve_descriptors 函數傳回)轉換為輸出陣列應使用的描述元。此函數必須傳回「可檢視」的類型,且不得以任何會破壞內部迴圈邏輯的形式變更它們。不需要支援 NULL。

包裝迴圈範例#

假設您想要為 WrappedDoubleDType 包裝 float64 乘法實作。您可以像這樣新增包裝迴圈

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

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

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

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

Py_DECREF(multiply);

請注意,這也需要在此程式碼上方定義兩個函數

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

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

用於呼叫陣列方法的 API#

轉換#

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

相當於 ndarray.getfield (self, dtype, offset)。此函數偷取了PyArray_Descr 的參考,並傳回使用目前陣列中指定 offset 位元組處的資料,以及給定 dtype 的新陣列。offset 加上新陣列類型的 itemsize 必須小於 self->descr->elsize,否則會引發錯誤。使用與原始陣列相同的形狀和 strides。因此,此函數的效果是從結構化陣列傳回欄位。但是,它也可以用於從任何陣列類型中選取特定位元組或位元組群組。

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 風格的連續陣列。如果 order 為 NPY_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 的大小一致。itemsize 必須相同,或者 self 必須是單一段,且位元組總數必須相同。在後一種情況下,傳回陣列的維度將在最後一個維度(或 Fortran 風格連續陣列的第一個維度)中變更。傳回陣列和 self 的資料區域完全相同。

形狀操作#

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

結果將是一個新陣列(如果可能,指向與 self 相同的記憶體位置),但具有 newshape 給定的形狀。如果新形狀與 self 的 strides 不相容,則會傳回具有新指定形狀的陣列副本。

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

相當於 ndarray.reshape (self, shape),其中 shape 是一個序列。將 shape 轉換為 PyArray_Dims 結構,並在內部呼叫 PyArray_Newshape。為了向後相容性 – 不建議使用

PyObject *PyArray_Squeeze(PyArrayObject *self)#

相當於 ndarray.squeeze (self)。傳回 self 的新檢視,其中所有長度為 1 的維度都已從形狀中移除。

警告

matrix 物件始終是 2 維的。因此,PyArray_Squeeze 對於 matrix 子類的陣列沒有影響。

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

相當於 ndarray.swapaxes (self, a1, a2)。 傳回的陣列是 self 中資料的新視圖,並交換了給定的軸 a1a2

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

相當於 ndarray.resize (self, newshape, refcheck = refcheck, order= fortran )。 此函數僅適用於單段陣列。 它會就地更改 self 的形狀,並且如果 newshape 的元素總數與舊形狀不同,則會重新分配 self 的記憶體。 如果需要重新分配,則 self 必須擁有其資料,具有 self - >base==NULL,具有 self - >weakrefs==NULL,並且(除非 refcheck 為 0)不能被任何其他陣列引用。 fortran 參數可以是 NPY_ANYORDERNPY_CORDERNPY_FORTRANORDER。 目前它沒有任何作用。 最終,它可以被用來決定當建構不同維度的陣列時,resize 操作應該如何看待資料。 成功時返回 None,錯誤時返回 NULL。

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

相當於 ndarray.transpose (self, permute)。 根據資料結構 permute 置換 ndarray 物件 self 的軸,並傳回結果。 如果 permuteNULL,則產生的陣列會使其軸反轉。 例如,如果 self 的形狀為 \(10\times20\times30\),且 permute .ptr 為 (0,2,1),則結果的形狀為 \(10\times30\times20.\) 如果 permuteNULL,則結果的形狀為 \(30\times20\times10.\)

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

相當於 ndarray.flatten (self, order)。 傳回陣列的 1 維副本。 如果 orderNPY_FORTRANORDER,則元素會以 Fortran 順序掃描出來(第一個維度變化最快)。 如果 orderNPY_CORDER,則 self 的元素會以 C 順序掃描(最後一個維度變化最快)。 如果 order NPY_ANYORDER,則使用 PyArray_ISFORTRAN (self) 的結果來決定要展平的順序。

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

相當於 self.ravel(order)。 與 PyArray_Flatten (self, order) 具有相同基本功能,但如果 order 為 0 且 self 是 C 風格連續的,則會更改形狀,但不執行複製。

項目選擇與操作#

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

相當於 ndarray.take (self, indices, axis, ret, clipmode),但 Python 中的 axis =None 是透過在 C 中設定 axis = NPY_MAXDIMS 來實現。 沿著給定的 axis,從 self 中提取由整數值 indices 指示的項目。 clipmode 參數可以是 NPY_RAISENPY_WRAPNPY_CLIP,以指示如何處理越界索引。 ret 參數可以指定輸出陣列,而不是在內部建立一個。

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

相當於 self.put(values, indices, clipmode )。 將 values 放入 self 中對應的(展平的)indices 位置。 如果 values 太小,它將會根據需要重複。

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

values 放置在 self 中,只要 mask 中對應位置(使用展平的上下文)為 true。 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,在這種情況下,會建立一個新的輸出。 當 self 中的條目不在 0 和 len(op) 之間時,clipmode 參數會決定行為。

NPY_RAISE#

引發 ValueError;

NPY_WRAP#

透過加上 len(op) 來包裝值 < 0,並透過減去 len(op) 來包裝值 >= len(op),直到它們在範圍內;

NPY_CLIP#

所有值都被裁剪到 [0, len(op) ) 區域。

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

相當於 ndarray.sort (self, axis, kind)。 傳回一個陣列,其中包含沿著 axis 排序的 self 的項目。 陣列使用由 kind 表示的演算法排序,kind 是一個指向所用排序演算法類型的整數/列舉。

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

相當於 ndarray.argsort (self, axis)。 傳回一個索引陣列,使得沿著給定的 axis 選擇這些索引將傳回 self 的排序版本。 如果 self ->descr 是具有已定義欄位的資料類型,則使用 self->descr->names 來決定排序順序。 第一個欄位相等的比較將使用第二個欄位,依此類推。 若要變更結構化陣列的排序順序,請建立具有不同名稱順序的新資料類型,並使用該新資料類型建構陣列的視圖。

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

給定形狀相同的陣列序列 (sort_keys),傳回一個索引陣列(類似於 PyArray_ArgSort (…)),該陣列將對陣列進行詞彙排序。 詞彙排序指定,當發現兩個鍵相等時,順序基於後續鍵的比較。 類型需要定義合併排序(保留相等條目不動)。 排序是透過首先使用第一個 sort_key 對索引進行排序,然後使用第二個 sort_key 等等來完成的。 這相當於 lexsort(sort_keys, axis) Python 命令。 由於合併排序的工作方式,請務必了解 sort_keys 必須處於的順序(與比較兩個元素時使用的順序相反)。

如果這些陣列都收集在結構化陣列中,那麼 PyArray_Sort (…) 也可以用於直接排序陣列。

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

相當於 ndarray.searchsorted (self, values, side, perm)。 假設 self 是一個升序排列的 1 維陣列,則輸出是一個與 values 形狀相同的索引陣列,這樣,如果將 values 中的元素插入到索引之前,self 的順序將被保留。 不會檢查 self 是否為升序排列。

side 參數指示傳回的索引應該是第一個合適位置的索引(如果是 NPY_SEARCHLEFT)還是最後一個合適位置的索引(如果是 NPY_SEARCHRIGHT)。

sorter 參數如果不是 NULL,則必須是與 self 長度相同的整數索引的 1 維陣列,它將 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 定義的 2 維陣列的 offset 對角線。

npy_intp PyArray_CountNonzero(PyArrayObject *self)#

計算陣列物件 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 )。(self, condition, axis ) 的等效函數。 傳回沿著軸 (axis) 且對應於 condition 中為 true 元素的元素。

運算#

提示

傳入 NPY_RAVEL_AXIS 作為 axis,以達到與在 Python 中傳入 axis=None 相同的效果(將陣列視為一維陣列)。

注意

out 參數指定放置結果的位置。如果 out 為 NULL,則會建立輸出陣列,否則輸出會放置在 out 中,而 out 必須是正確的大小和類型。即使 out 不為 NULL,也總是會傳回對輸出陣列的新參考。常式的呼叫者有責任在 out 不為 NULL 時 Py_DECREF out,否則會發生記憶體洩漏。

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

等同於 ndarray.argmax (self, axis)。(self, axis) 的等效函數。 傳回沿著軸 (axis)self 最大元素的索引。

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

等同於 ndarray.argmin (self, axis)。(self, axis) 的等效函數。 傳回沿著軸 (axis)self 最小元素的索引。

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

等同於 ndarray.max (self, axis)。(self, axis) 的等效函數。 傳回沿著給定軸 (axis)self 最大元素。當結果是單一元素時,傳回 numpy 純量而不是 ndarray。

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

等同於 ndarray.min (self, axis)。(self, axis) 的等效函數。 傳回沿著給定軸 (axis)self 最小元素。當結果是單一元素時,傳回 numpy 純量而不是 ndarray。

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

傳回沿著軸 (axis)self 最大元素與沿著軸 (axis)self 最小元素之間的差值。當結果是單一元素時,傳回 numpy 純量而不是 ndarray。

注意

rtype 參數指定縮減應發生的資料類型。如果陣列的資料類型不夠「大」以處理輸出,這點非常重要。預設情況下,所有整數資料類型至少會與 NPY_LONG 一樣大,適用於「add」和「multiply」ufunc(它們構成 mean、sum、cumsum、prod 和 cumprod 函數的基礎)。

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

等同於 ndarray.mean (self, axis, rtype)。(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)。(self, offset, axis1, axis2, rtype) 的等效函數。 傳回由 axis1axis2 變數定義的二維陣列的 offset 對角線元素的總和(使用 rtype 作為求和的資料類型)。正 offset 選擇主對角線以上的對角線。負 offset 選擇主對角線以下的對角線。

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

等同於 ndarray.clip (self, min, max)。(self, min, max) 的等效函數。 裁剪陣列 self,使大於 max 的值固定為 max,且小於 min 的值固定為 min

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

等同於 ndarray.conjugate (self)。(self) 的等效函數。 傳回 self 的共軛複數。如果 self 不是複數資料類型,則傳回帶有參考的 self

參數:
  • self – 輸入陣列。

  • out – 輸出陣列。如果提供,結果會放入此陣列中。

傳回:

self 的共軛複數。

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

等同於 ndarray.round (self, decimals, out)。(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)。(self, axis, rtype) 的等效函數。 傳回使用沿著軸 (axis) 的資料轉換為資料類型 rtype 的標準差。

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

等同於 ndarray.sum (self, axis, rtype)。(self, axis, rtype) 的等效函數。 傳回沿著軸 (axis)self 元素的一維向量總和。在將資料轉換為資料類型 rtype 後執行總和。

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

等同於 ndarray.cumsum (self, axis, rtype)。(self, axis, rtype) 的等效函數。 傳回沿著軸 (axis)self 元素的一維累積總和。在將資料轉換為資料類型 rtype 後執行總和。

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

等同於 ndarray.prod (self, axis, rtype)。(self, axis, rtype) 的等效函數。 傳回沿著軸 (axis)self 元素的一維乘積。在將資料轉換為資料類型 rtype 後執行乘積。

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

等同於 ndarray.cumprod (self, axis, rtype)。(self, axis, rtype) 的等效函數。 傳回沿著 axisself 元素的一維累積乘積。在將資料轉換為資料類型 rtype 後執行乘積。

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

等同於 ndarray.all (self, axis)。(self, axis) 的等效函數。 傳回一個陣列,其中對於由 axis 定義的 self 的每個一維子陣列,如果所有元素皆為 True,則元素為 True。

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

等同於 ndarray.any (self, axis)。(self, axis) 的等效函數。 傳回一個陣列,其中對於由 axis 定義的 self 的每個一維子陣列,如果任何元素為 True,則元素為 True。

函式#

陣列函式#

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

有時,將多維陣列作為 C 語言風格的多維陣列存取會很有用,以便可以使用 C 的 a[i][j][k] 語法來實作演算法。此常式傳回一個指標 ptr,它模擬這種 C 語言風格的陣列,適用於 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)。

  • typedescrPyArray_Descr 結構,指示所需的資料類型(包括所需的位元組順序)。呼叫將竊取對參數的參考。

注意

對於 2 維和 3 維陣列,C 語言風格陣列的模擬並不完整。例如,模擬的指標陣列無法傳遞給期望特定、靜態定義的 2 維和 3 維陣列的子常式。若要傳遞給需要這些種類輸入的函式,您必須靜態定義所需的陣列並複製資料。

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

必須使用從 PyArray_AsCArray (…​) 傳回的相同物件和記憶體位置來呼叫。此函式清理否則會洩漏的記憶體。

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

沿著軸 (axis)obj 中的物件序列聯結成單一陣列。如果維度或類型不相容,則會引發錯誤。

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

計算 obj1obj2 最後維度的乘積和。兩個陣列均未共軛。

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

計算 obj1 最後一個維度和 obj2 倒數第二個維度的乘積和。對於二維陣列,這是矩陣乘積。兩個陣列均未共軛。

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

與 PyArray_MatrixProduct 相同,但將結果儲存在 out 中。 輸出陣列必須具有正確的形狀、類型,並且是 C 連續的,否則會引發例外。

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

將愛因斯坦求和約定應用於提供的陣列運算元,傳回一個新陣列或將結果放置在 out 中。subscripts 中的字串是以逗號分隔的索引字母列表。運算元的數量在 nop 中,而 op_in 是一個包含這些運算元的陣列。輸出的資料類型可以使用 dtype 強制指定,輸出順序可以使用 order 強制指定(建議使用 NPY_KEEPORDER),並且當指定 dtype 時,casting 指示資料轉換應該有多寬容。

有關更多詳細資訊,請參閱 einsum 函數。

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

計算 1 維陣列 op1op2 的 1 維相關性。通過將 op1 乘以 op2 的移位版本並對結果求和,在每個輸出點計算相關性。由於移位的結果,op1op2 定義範圍之外的所需值被解釋為零。模式決定了要返回多少個移位:0 - 僅返回不需要假定零值的移位;1 - 返回與 op1 大小相同的物件,2 - 返回所有可能的移位(接受任何重疊)。

備註

這不會計算通常的相關性:如果 op2 大於 op1,則會交換參數,並且永遠不會對複數陣列取共軛。有關通常的訊號處理相關性,請參閱 PyArray_Correlate2。

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

PyArray_Correlate 的更新版本,它對 1 維陣列使用相關性的常用定義。通過將 op1 乘以 op2 的移位版本並對結果求和,在每個輸出點計算相關性。由於移位的結果,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 相同,並具有 xy 的元素,其中 condition 分別為 True 或 False。

其他函數#

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

確定 newstrides 是否為與 nd 維陣列的記憶體一致的 strides 陣列,該陣列具有形狀 dims 和元素大小 elsize。檢查 newstrides 陣列,以查看在每個方向上跳轉提供的位元組數是否會意味著跳轉超過 numbytes,而 numbytes 是可用記憶體段的假定大小。如果 numbytes 為 0,則計算等效的 numbytes,假設 nddimselsize 指的是單個段陣列。如果 newstrides 可接受,則傳回 NPY_TRUE,否則傳回 NPY_FALSE

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

這兩個常式都將一個長度為 n 的整數陣列 seq 相乘,並傳回結果。不執行溢位檢查。

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

給定兩個長度為 n 的整數陣列 l1l2,如果列表相同則傳回 1;否則,傳回 0。

具有物件語義的輔助資料#

type NpyAuxData#

當處理由其他 dtype 組成的更複雜的 dtype 時,例如 struct dtype,建立操作 dtype 的內部迴圈需要攜帶額外的資料。NumPy 通過 struct 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 是陣列迭代器(或是陣列迭代器類型的子類的實例),則評估為 true。

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 個迭代器的資料指標。

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 新增。

傳回多重迭代器物件的廣播結果中目前的 (1 維) 索引。

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 維版本通常針對速度進行了最佳化,因此迴圈應在不需要大步幅跳躍的軸上執行。

鄰域迭代器#

鄰域迭代器是迭代器物件的子類別,可用於迭代點的鄰域。例如,您可能想要迭代 3d 影像的每個體素,並針對每個此類體素,迭代超立方體。鄰域迭代器會自動處理邊界,因此使此類程式碼比手動邊界處理更容易編寫,但代價是略微的效能開銷。

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

此函數從現有的迭代器建立新的鄰域迭代器。鄰域將相對於 iter 當前指向的位置計算,bounds 定義鄰域迭代器的形狀,而 mode 引數定義邊界處理模式。

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,則需要 base。否則,base 可能為 NULL

如果資料不是原生位元組順序(如 dtype->byteorder 所指示),則此函數將交換位元組,因為陣列純量始終採用正確的機器位元組順序。

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

傳回由陣列物件 arr 指示的類型和項目大小的陣列純量物件,從 data 指向的記憶體複製,如果 arr 中的資料不是機器位元組順序,則交換位元組。

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

scalar 傳回由 outcode 決定的類型之 0 維陣列,scalar 應為陣列純量物件。如果 outcode 為 NULL,則從 scalar 決定類型。

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

ctypeptr 中傳回指向陣列純量中實際值的指標。沒有錯誤檢查,因此 scalar 必須是陣列純量物件,並且 ctypeptr 必須有足夠的空間來容納正確的類型。對於彈性大小的類型,資料的指標會複製到 ctypeptr 的記憶體中,對於所有其他類型,實際資料會複製到 ctypeptr 指向的位址。

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

傳回來自陣列純量 scalar 的資料(轉換為 outcode 指示的資料類型),到 ctypeptr 指向的記憶體中(該記憶體必須足夠大以處理傳入的記憶體)。

失敗時傳回 -1,成功時傳回 0。

PyObject *PyArray_TypeObjectFromType(int type)#

從類型編號 type 傳回純量類型物件。等效於 PyArray_DescrFromType (type)->typeobj,但參考計數和錯誤檢查除外。成功時傳回對類型物件的新參考,失敗時傳回 NULL

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

查詢純量值特殊升級的舊方法。NumPy 本身不再使用此方法,預計最終會被棄用。

新的 DType 可以定義特定於 Python 純量的升級規則。

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

查詢純量值特殊升級的舊方法。NumPy 本身不再使用此方法,預計最終會被棄用。

針對類似目的使用 PyArray_ResultType

資料類型描述器#

警告

資料類型物件必須進行參考計數,因此請注意不同 C-API 呼叫對資料類型參考的作用。標準規則是,當傳回資料類型物件時,它是一個新的參考。接受 PyArray_Descr* 物件並傳回陣列的函數會盜用對其輸入資料類型的參考,除非另有說明。因此,您必須擁有對用作此類函數輸入的任何資料類型物件的參考。

int PyArray_DescrCheck(PyObject *obj)#

如果 obj 是資料類型物件 ( PyArray_Descr* ),則評估為 true。

PyArray_Descr *PyArray_DescrNew(PyArray_Descr *obj)#

傳回從 obj 複製的新資料類型物件(欄位參考僅更新,以便新物件指向相同的欄位字典,如果有的話)。

PyArray_Descr *PyArray_DescrNewFromType(int typenum)#

typenum 指示的內建(或使用者註冊)資料類型建立新的資料類型物件。所有內建類型都不應更改其任何欄位。這會建立 PyArray_Descr 結構的新副本,以便您可以適當地填寫它。此函數對於彈性資料類型尤其需要,彈性資料類型需要新的 elsize 成員才能在陣列建構中具有意義。

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

建立一個新的資料類型物件,其位元組順序根據 newendian 設定。所有參考的資料類型物件(在資料類型物件的 subdescr 和 fields 成員中)也會被更改(遞迴地)。

newendian 的值是這些巨集之一

NPY_IGNORE#
NPY_SWAP#
NPY_NATIVE#
NPY_LITTLE#
NPY_BIG#

如果遇到 NPY_IGNORE 的位元組順序,則保持不變。如果 newendian 是 NPY_SWAP,則所有位元組順序都會交換。其他有效的 newendian 值為 NPY_NATIVENPY_LITTLENPY_BIG,它們都會導致傳回的資料類型描述器(及其所有參考的資料類型描述器)具有相應的位元組順序。

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

從物件 op (應為「巢狀」序列物件)和最小資料類型描述器 mintype(可以為 NULL)決定適當的資料類型物件。行為類似於 array(op).dtype。不要將此函數與 PyArray_DescrConverter 混淆。此函數基本上會查看(巢狀)序列中的所有物件,並從它找到的元素決定資料類型。

PyArray_Descr *PyArray_DescrFromScalar(PyObject *scalar)#

從陣列純量物件傳回資料類型物件。不進行檢查以確保 scalar 是陣列純量。如果無法決定合適的資料類型,則預設情況下會傳回 NPY_OBJECT 的資料類型。

PyArray_Descr *PyArray_DescrFromType(int typenum)#

傳回對應於 typenum 的資料類型物件。typenum 可以是其中一種列舉類型、其中一種列舉類型的字元代碼或使用者定義的類型。如果您想使用彈性大小的陣列,則需要 flexible typenum 並將結果 elsize 參數設定為所需的大小。typenum 是 NPY_TYPES 之一。

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

將任何相容的 Python 物件 obj 轉換為 dtype 中的資料類型物件。大量 Python 物件可以轉換為資料類型物件。請參閱 資料類型物件 (dtype) 以取得完整說明。此轉換器的版本將 None 物件轉換為 NPY_DEFAULT_TYPE 資料類型物件。此函數可以與 PyArg_ParseTuple 處理中的 “O&” 字元代碼一起使用。

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

轉換任何相容的 Python 物件,obj,成為 dtype 中的資料型態物件。此轉換器版本會轉換 None 物件,以便傳回的資料型態為 NULL。此函數也可以與 PyArg_ParseTuple 處理中的 “O&” 字元一起使用。

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

類似於 PyArray_DescrConverter,但它會像編譯器一樣,將類似 C 結構的物件對齊到 word 邊界。

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

類似於 PyArray_DescrConverter2,但它會像編譯器一樣,將類似 C 結構的物件對齊到 word 邊界。

資料型態提升與檢查#

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

此函數定義了 common DType 運算子。請注意,common 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 repository。 另請參閱 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 repository 中的範例。

旗標#

可以在 PyArrayDTypeMeta_Spec 上設定的旗標,以初始化 DType。

NPY_DT_ABSTRACT#

表示 DType 是 DType 階層中的抽象「基礎」DType,不應直接實例化。

NPY_DT_PARAMETRIC#

表示 DType 是參數化的,並且沒有唯一的 singleton 實例。

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 的預設描述器實例。必須為參數化資料型態定義。非參數化資料型態預設傳回 singleton。

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

給定兩個輸入 DType,決定適合的「common」DType,該 DType 可以儲存這兩種型別的值。如果不存在此類型別,則傳回 Py_NotImplemented

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

給定兩個輸入描述器,決定適合的「common」描述器,該描述器可以儲存這兩個實例的值。發生錯誤時傳回 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 內部針對需要寫入表示零的自訂 sentinel 值的陣列呼叫,以防因某種原因,填滿零的陣列不足夠。實作 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#

允許設定每個 dtype 的 getitem。 請注意,除非呼叫以 NPY_DT_getitem ID 定義的函數的預設版本不適用,否則不必定義此項。 此版本會比使用 NPY_DT_getitem 稍快,但代價是有時需要處理 NULL 輸入陣列。

NPY_DT_PyArray_ArrFuncs_setitem#

允許設定每個 dtype 的 setitem。 請注意,除非呼叫以 NPY_DT_setitem ID 定義的函數的預設版本因故不適用,否則不必定義此項。

NPY_DT_PyArray_ArrFuncs_compare#

計算 numpy.sort 的比較,實作 PyArray_CompareFunc

NPY_DT_PyArray_ArrFuncs_argmax#

計算 numpy.argmax 的 argmax,實作 PyArray_ArgFunc

NPY_DT_PyArray_ArrFuncs_argmin#

計算 numpy.argmin 的 argmin,實作 PyArray_ArgFunc

NPY_DT_PyArray_ArrFuncs_dotfunc#

計算 numpy.dot 的點積,實作 PyArray_DotFunc

NPY_DT_PyArray_ArrFuncs_scanfunc#

numpy.fromfile 的格式化輸入函數,實作 PyArray_ScanFunc

NPY_DT_PyArray_ArrFuncs_fromstr#

numpy.fromstring 的字串剖析函數,實作 PyArray_FromStrFunc

NPY_DT_PyArray_ArrFuncs_nonzero#

計算 numpy.nonzero 的 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 演算法定義自訂 argsort 實作。

巨集與靜態內聯函數#

提供這些巨集和靜態內聯函數,以便在使用 PyArray_DTypeMeta 實例時,能夠編寫更易於理解和慣用的程式碼。

NPY_DTYPE(descr)#

傳回一個 PyArray_DTypeMeta * 指標,指向給定描述器實例的 DType。

static inline PyArray_DTypeMeta *NPY_DT_NewRef(PyArray_DTypeMeta *o)#

傳回一個 PyArray_DTypeMeta * 指標,指向 DType 的新參考。

轉換工具#

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

這是提供給函數的輸出陣列的預設轉換器。 如果 *obj* 是 Py_NoneNULL,則 *address* 將為 NULL,但呼叫將會成功。 如果 PyArray_Check ( *obj*) 為 TRUE,則會在 **address** 中傳回它,而不會遞增其參考計數。

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

轉換任何小於 NPY_MAXDIMS 的 Python 序列 objnpy_intp 的 C 陣列。Python 物件也可以是單一數字。seq 變數是指向具有成員 ptr 和 len 的結構的指標。成功返回時,seq ->ptr 包含指向必須釋放的記憶體的指標,透過呼叫 PyDimMem_FREE 以避免記憶體洩漏。記憶體大小的限制允許此轉換器方便地用於預期被解釋為陣列形狀的序列。

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

轉換任何具有(單段)緩衝區介面的 Python 物件 obj 為具有成員的變數,這些成員詳細說明物件對其記憶體區塊的使用。PyArray_Chunk 變數是指向具有 base、ptr、len 和 flags 成員的結構的指標。PyArray_Chunk 結構與 Python 的緩衝區物件二進位相容(透過其在 32 位元平台上的 len 成員和在 64 位元平台上的 ptr 成員)。返回時,base 成員設定為 obj(或其 base,如果 obj 已經是指向另一個物件的緩衝區物件)。如果您需要保留記憶體,請務必 INCREF base 成員。記憶體區塊由 buf ->ptr 成員指向,長度為 buf ->len。buf 的 flags 成員是 NPY_ARRAY_ALIGNED,且如果 obj 具有可寫入的緩衝區介面,則設定 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 物件 objNPY_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>

您也可以將常見的最後兩行放入擴充本機標頭檔中,只要您確保在 #including 該檔案之前 #defined NO_IMPORT_ARRAY 即可。

在內部,這些 #defines 的運作方式如下

  • 如果兩者都未定義,則 C-API 被宣告為 static void**,因此它僅在 #includes numpy/arrayobject.h 的編譯單元中可見。

  • 如果 #defined 了 PY_ARRAY_UNIQUE_SYMBOL,但未 #defined NO_IMPORT_ARRAY,則 C-API 被宣告為 void**,因此它也將對其他編譯單元可見。

  • 如果 #defined 了 NO_IMPORT_ARRAY,無論是否 #defined 了 PY_ARRAY_UNIQUE_SYMBOL,C-API 都被宣告為 extern void**,因此預期在另一個編譯單元中定義它。

  • 每當 #defined 了 PY_ARRAY_UNIQUE_SYMBOL 時,它也會變更持有 C-API 的變數的名稱,預設為 PyArray_API,變更為巨集 #defined 的任何名稱。

檢查 API 版本#

由於 python 擴充功能的使用方式與大多數平台上的常用程式庫不同,因此某些錯誤無法在建置時甚至執行時自動偵測到。例如,如果您使用僅適用於 numpy >= 1.3.0 的函式建置擴充功能,然後稍後使用 numpy 1.2 匯入擴充功能,您將不會收到匯入錯誤(但幾乎可以肯定在呼叫函式時會發生區段錯誤)。這就是為什麼提供多個函式來檢查 numpy 版本的原因。巨集 NPY_VERSIONNPY_FEATURE_VERSION 對應於用於建置擴充功能的 numpy 版本,而函式 PyArray_GetNDArrayCVersionPyArray_GetNDArrayCFeatureVersion 返回的版本對應於執行時 numpy 的版本。

ABI 和 API 相容性的規則可以總結如下

  • 每當 NPY_VERSION != PyArray_GetNDArrayCVersion() 時,擴充功能都必須重新編譯(ABI 不相容)。

  • NPY_VERSION == PyArray_GetNDArrayCVersion()NPY_FEATURE_VERSION <= PyArray_GetNDArrayCFeatureVersion() 表示向後相容的變更。

NumPy 的每個版本都會自動偵測 ABI 不相容性。API 不相容性偵測是在 NumPy 1.4.0 版本中加入的。如果您希望使用一個擴充二進制檔案來支援多個不同的 NumPy 版本,則必須使用儘可能低的 NPY_FEATURE_VERSION 來建置您的擴充功能。

NPY_VERSION#

ndarray 物件的目前版本(檢查是否定義了此變數,以確保正在使用 numpy/arrayobject.h 標頭檔)。

NPY_FEATURE_VERSION#

C-API 的目前版本。

unsigned int PyArray_GetNDArrayCVersion(void)#

這只會傳回值 NPY_VERSIONNPY_VERSION 會在 ABI 層級發生向後不相容的變更時變更。然而,由於它位於 C-API 中,因此比較此函數的輸出與目前標頭檔中定義的值,可以測試 C-API 是否已變更,從而判斷是否需要重新編譯使用 C-API 的擴充模組。這會在函數 import_array 中自動檢查。

unsigned int PyArray_GetNDArrayCFeatureVersion(void)#

這只會傳回值 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)#

用於配置、釋放和重新配置維度和 strides 記憶體的巨集。

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

這些巨集使用不同的記憶體配置器,具體取決於常數 NPY_USE_PYMEM。當 NPY_USE_PYMEM 為 0 時,會使用系統 malloc;如果 NPY_USE_PYMEM 為 1,則會使用 Python 記憶體配置器。

NPY_USE_PYMEM#
int PyArray_ResolveWritebackIfCopy(PyArrayObject *obj)#

如果 obj->flags 具有 NPY_ARRAY_WRITEBACKIFCOPY,此函數會清除旗標,DECREF obj->base 並使其可寫入,並將 obj->base 設定為 NULL。然後,它會將 obj->data 複製到 obj->base->data,並傳回複製操作的錯誤狀態。這與 PyArray_SetWritebackIfCopyBase 相反。通常,當您完成使用 obj 時,在 Py_DECREF(obj) 之前呼叫此函數。它可以多次呼叫,或使用 NULL 輸入。另請參閱 PyArray_DiscardWritebackIfCopy

如果沒有執行任何操作,則傳回 0;如果發生錯誤,則傳回 -1;如果執行了操作,則傳回 1。

執行緒支援#

這些巨集僅在編譯擴充模組期間 NPY_ALLOW_THREADS 評估為 True 時才有意義。否則,這些巨集等同於空白字元。Python 為每個 Python 程序使用單一全域直譯器鎖定 (GIL),因此一次只能執行一個執行緒(即使在多 CPU 電腦上也是如此)。當呼叫可能需要一些時間才能計算完成的已編譯函數(並且對於其他執行緒沒有副作用,例如更新全域變數)時,應釋放 GIL,以便其他 Python 執行緒可以在執行耗時計算時執行。這可以使用兩組巨集來完成。通常,如果一組巨集中的一個巨集在程式碼區塊中使用,則所有巨集都必須在同一個程式碼區塊中使用。NPY_ALLOW_THREADS 為 true(定義為 1),除非建置選項 -Ddisable-threading 設定為 true - 在這種情況下,NPY_ALLOW_THREADS 為 false (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#

此群組用於在 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 可能使用的最大維度數。這設定為 64,在 NumPy 2 之前為 32。

注意

我們建議您避免使用 NPY_MAXDIMS。NumPy 的未來版本可能希望移除任何維度限制(以及常數)。建立此限制是為了讓 NumPy 可以在內部使用堆疊配置作為暫存空間。

如果您的演算法具有合理的維度最大數量,您可以檢查並在本地使用它。

NPY_MAXARGS#

某些函數中可以使用的最大陣列引數數量。在 NumPy 2 之前,這曾經是 32,現在是 64。為了繼續允許將其用作檢查引數數量是否與 ufuncs 相容的檢查,此巨集現在取決於執行階段。

注意

我們不鼓勵任何非明確與檢查已知 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,此函數會清除旗標,DECREF obj->base 並使其可寫入,並將 obj->base 設定為 NULL。與 PyArray_ResolveWritebackIfCopy 相反,它不會嘗試從 obj->base 複製資料。這會撤銷 PyArray_SetWritebackIfCopyBase。通常,當您完成使用 obj 時,在 Py_DECREF(obj) 之前呼叫此函數。它可以多次呼叫,或使用 NULL 輸入。

列舉型別#

enum NPY_SORTKIND#

一種特殊的變數型別,可以採用不同的值來指示正在使用的排序演算法。

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

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

enumerator NPY_NSORTS#

定義為排序的數量。由於需要向後相容性,因此它固定為三個,因此 NPY_MERGESORTNPY_STABLESORT 彼此互為別名,並且可能指代多種穩定的排序演算法之一,具體取決於資料型別。

enum NPY_SCALARKIND#

一種特殊的變數型別,指示在確定純量強制轉換規則時區分的純量「種類」的數量。此變數可以採用以下值

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

定義為純量種類的數量(不包括 NPY_NOSCALAR)。

enum NPY_ORDER#

一種列舉型別,指示應在其中解釋陣列的元素順序。當建立全新的陣列時,通常只使用 NPY_CORDERNPY_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#

列舉類型,指示資料轉換應有多寬鬆。這用於 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#

允許任何轉換,無論可能發生何種資料遺失。