User guide
NumPy User Guide, Release 1.9.0
— Albert Szent-Gyorgi
5.4.1 Iterating over elements in the array
Basic Iteration
One common algorithmic requirement is to be able to walk over all elements in a multidimensional array. The array
iterator object makes this easy to do in a generic way that works for arrays of any dimension. Naturally, if you know
the number of dimensions you will be using, then you can always write nested for loops to accomplish the iteration.
If, however, you want to write code that works with any number of dimensions, then you can make use of the array
iterator. An array iterator object is returned when accessing the .flat attribute of an array.
Basic usage is to call PyArray_IterNew ( array ) where array is an ndarray object (or one of its sub-classes).
The returned object is an array-iterator object (the same object returned by the .flat attribute of the ndarray). This
object is usually cast to PyArrayIterObject* so that its members can be accessed. The only members that are needed
are iter->size which contains the total size of the array, iter->index, which contains the current 1-d index
into the array, and iter->dataptr which is a pointer to the data for the current element of the array. Sometimes it
is also useful to access iter->ao which is a pointer to the underlying ndarray object.
After processing data at the current element of the array, the next element of the array can be obtained using the macro
PyArray_ITER_NEXT ( iter ). The iteration always proceeds in a C-style contiguous fashion (last index varying
the fastest). The PyArray_ITER_GOTO ( iter, destination ) can be used to jump to a particular point in the
array, where destination is an array of npy_intp data-type with space to handle at least the number of dimensions
in the underlying array. Occasionally it is useful to use PyArray_ITER_GOTO1D ( iter, index ) which will
jump to the 1-d index given by the value of index. The most common usage, however, is given in the following
example.
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);
}
...
You can also use PyArrayIter_Check ( obj ) to ensure you have an iterator object and PyArray_ITER_RESET
( iter ) to reset an iterator object back to the beginning of the array.
It should be emphasized at this point that you may not need the array iterator if your array is already contiguous (using
an array iterator will work but will be slower than the fastest code you could write). The major purpose of array
iterators is to encapsulate iteration over N-dimensional arrays with arbitrary strides. They are used in many, many
places in the NumPy source code itself. If you already know your array is contiguous (Fortran or C), then simply
adding the element- size to a running pointer variable will step you through the array very efficiently. In other words,
code like this will probably be faster for you in the contiguous case (assuming doubles).
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++;
}
5.4. Beyond the Basics 99