一種常見的算法要求是能夠周遊多元數組中的所有元素。數組疊代器對象使這種方法易于以通用方式完成,适用于任何次元的數組。當然,如果您知道要使用的維數,那麼您始終可以編寫嵌套for循環來完成疊代。但是,如果要編寫适用于任意數量次元的代碼,則可以使用數組疊代器。通路數組的.flat屬性時傳回數組疊代器對象。
基本用法是調用PyArray_IterNew
(array),其中array是ndarray對象(或其子類之一)。傳回的對象是一個array-iterator對象(由ndarray的.flat屬性傳回的同一對象)。此對象通常強制轉換為PyArrayIterObject *,以便可以通路其成員。所需的唯一成員iter->size包含數組的總大小iter->index,其中包含數組的目前1-d索引,以及iter->dataptr指向數組目前元素的資料的指針。有時,通路iter->ao哪個是指向底層ndarray對象的指針也很有用。
在數組的目前元素處理資料之後,可以使用macro PyArray_ITER_NEXT
(iter)擷取數組的下一個元素
。疊代總是以C風格的連續方式進行(最後一個索引變化最快)。的
PyArray_ITER_GOTO (iter,destination)可以用來跳到一個特定點的數組,其中在destination是npy_intp資料類型與空間的數組,以處理潛在的數組中的次元中的至少數。有時使用PyArray_ITER_GOTO1D
(iter,index)将跳轉到由值給出的1-d索引是有用的index。但是,最常見的用法在以下示例中給出。
PyObject *obj; /* assumed to be some ndarray object */
PyArrayIterObject *iter;
...
iter = (PyArrayIterObject *)PyArray_IterNew(obj);
if (iter == NULL) goto fail; /* Assume fail has clean-up code */
while (iter->index < iter->size) {
/* do something with the data at it->dataptr */
PyArray_ITER_NEXT(it);
}
…
您還可以使用PyArrayIter_Check
(obj)來確定您擁有疊代器對象和PyArray_ITER_RESET
(iter)以将疊代器對象重置回數組的開頭。
在這一點上應該強調的是,如果你的數組已經是連續的,你可能不需要數組疊代器(使用數組疊代器可以工作,但會比你寫的最快的代碼慢)。數組疊代器的主要目的是使用任意步長将疊代封裝在N維數組上。它們在NumPy源代碼本身的許多地方使用。如果您已經知道您的數組是連續的(Fortran或C),那麼隻需将元素大小添加到正在運作的指針變量就可以非常有效地引導您完成數組。換句話說,在連續的情況下(假設為雙精度),這樣的代碼可能會更快。
npy_intp size;
double *dptr; /* could make this any variable type */
size = PyArray_SIZE(obj);
dptr = PyArray_DATA(obj);
while(size--) {
/* do something with the data at dptr */
dptr++;
}
疊代除一個軸之外的所有軸
一種常見的算法是循環周遊數組的所有元素,并通過發出函數調用對每個元素執行一些函數。由于函數調用可能非常耗時,是以加速此類算法的一種方法是編寫函數,使其擷取資料向量,然後編寫疊代,以便一次對整個資料次元執行函數調用。這增加了每個函數調用完成的工作量,進而将函數調用開頭減少到總時間的一小部分。即使在沒有函數調用的情況下執行循環的内部,在具有最大數量元素的次元上執行内循環也是有利的,以利用在使用流水線操作來增強基礎操作的微處理器上可用的速度增強。
的PyArray_IterAllButAxis
(array,&dim)構造被修改,使得它不會在由暗淡訓示的尺寸疊代的疊代器對象。這個疊代器對象的唯一限制是不能使用PyArray_Iter_GOTO1D(it,ind)宏(是以,如果将此對象傳遞回Python,則平面索引将不起作用 - 是以你不應該這樣做)。請注意,此例程中傳回的對象仍然通常轉換為PyArrayIterObject *。所做的就是修改傳回疊代器的步幅和尺寸,以模拟疊代數組[…,0,…],其中0放在
次元上。如果dim為負,則找到并使用具有最大軸的尺寸。
更多請見:http://www.mark-to-win.com/tutorial/52200.html