numpy.nditer — NumPy v2.2 Manual (original) (raw)

class numpy.nditer(op, flags=None, op_flags=None, op_dtypes=None, order='K', casting='safe', op_axes=None, itershape=None, buffersize=0)[source]#

Efficient multi-dimensional iterator object to iterate over arrays. To get started using this object, see theintroductory guide to array iteration.

Parameters:

opndarray or sequence of array_like

The array(s) to iterate over.

flagssequence of str, optional

Flags to control the behavior of the iterator.

op_flagslist of list of str, optional

This is a list of flags for each operand. At minimum, one ofreadonly, readwrite, or writeonly must be specified.

op_dtypesdtype or tuple of dtype(s), optional

The required data type(s) of the operands. If copying or buffering is enabled, the data will be converted to/from their original types.

order{‘C’, ‘F’, ‘A’, ‘K’}, optional

Controls the iteration order. ‘C’ means C order, ‘F’ means Fortran order, ‘A’ means ‘F’ order if all the arrays are Fortran contiguous, ‘C’ order otherwise, and ‘K’ means as close to the order the array elements appear in memory as possible. This also affects the element memory order of allocate operands, as they are allocated to be compatible with iteration order. Default is ‘K’.

casting{‘no’, ‘equiv’, ‘safe’, ‘same_kind’, ‘unsafe’}, optional

Controls what kind of data casting may occur when making a copy or buffering. Setting this to ‘unsafe’ is not recommended, as it can adversely affect accumulations.

op_axeslist of list of ints, optional

If provided, is a list of ints or None for each operands. The list of axes for an operand is a mapping from the dimensions of the iterator to the dimensions of the operand. A value of -1 can be placed for entries, causing that dimension to be treated as newaxis.

itershapetuple of ints, optional

The desired shape of the iterator. This allows allocate operands with a dimension mapped by op_axes not corresponding to a dimension of a different operand to get a value not equal to 1 for that dimension.

buffersizeint, optional

When buffering is enabled, controls the size of the temporary buffers. Set to 0 for the default value.

Notes

nditer supersedes flatiter. The iterator implementation behindnditer is also exposed by the NumPy C API.

The Python exposure supplies two iteration interfaces, one which follows the Python iterator protocol, and another which mirrors the C-style do-while pattern. The native Python approach is better in most cases, but if you need the coordinates or index of an iterator, use the C-style pattern.

Examples

Here is how we might write an iter_add function, using the Python iterator protocol:

def iter_add_py(x, y, out=None): ... addop = np.add ... it = np.nditer([x, y, out], [], ... [['readonly'], ['readonly'], ['writeonly','allocate']]) ... with it: ... for (a, b, c) in it: ... addop(a, b, out=c) ... return it.operands[2]

Here is the same function, but following the C-style pattern:

def iter_add(x, y, out=None): ... addop = np.add ... it = np.nditer([x, y, out], [], ... [['readonly'], ['readonly'], ['writeonly','allocate']]) ... with it: ... while not it.finished: ... addop(it[0], it[1], out=it[2]) ... it.iternext() ... return it.operands[2]

Here is an example outer product function:

def outer_it(x, y, out=None): ... mulop = np.multiply ... it = np.nditer([x, y, out], ['external_loop'], ... [['readonly'], ['readonly'], ['writeonly', 'allocate']], ... op_axes=[list(range(x.ndim)) + [-1] * y.ndim, ... [-1] * x.ndim + list(range(y.ndim)), ... None]) ... with it: ... for (a, b, c) in it: ... mulop(a, b, out=c) ... return it.operands[2]

a = np.arange(2)+1 b = np.arange(3)+1 outer_it(a,b) array([[1, 2, 3], [2, 4, 6]])

Here is an example function which operates like a “lambda” ufunc:

def luf(lamdaexpr, *args, **kwargs): ... '''luf(lambdaexpr, op1, ..., opn, out=None, order='K', casting='safe', buffersize=0)''' ... nargs = len(args) ... op = (kwargs.get('out',None),) + args ... it = np.nditer(op, ['buffered','external_loop'], ... [['writeonly','allocate','no_broadcast']] + ... [['readonly','nbo','aligned']]*nargs, ... order=kwargs.get('order','K'), ... casting=kwargs.get('casting','safe'), ... buffersize=kwargs.get('buffersize',0)) ... while not it.finished: ... it[0] = lamdaexpr(*it[1:]) ... it.iternext() ... return it.operands[0]

a = np.arange(5) b = np.ones(5) luf(lambda i,j:i*i + j/2, a, b) array([ 0.5, 1.5, 4.5, 9.5, 16.5])

If operand flags "writeonly" or "readwrite" are used the operands may be views into the original data with the_WRITEBACKIFCOPY_ flag. In this case nditer must be used as a context manager or the nditer.close method must be called before using the result. The temporary data will be written back to the original data when the __exit__ function is called but not before:

a = np.arange(6, dtype='i4')[::-2] with np.nditer(a, [], ... [['writeonly', 'updateifcopy']], ... casting='unsafe', ... op_dtypes=[np.dtype('f4')]) as i: ... x = i.operands[0] ... x[:] = [-1, -2, -3] ... # a still unchanged here a, x (array([-1, -2, -3], dtype=int32), array([-1., -2., -3.], dtype=float32))

It is important to note that once the iterator is exited, dangling references (like x in the example) may or may not share data with the original data a. If writeback semantics were active, i.e. if_x.base.flags.writebackifcopy_ is True, then exiting the iterator will sever the connection between x and a, writing to x will no longer write to a. If writeback semantics are not active, then_x.data_ will still point at some part of a.data, and writing to one will affect the other.

Context management and the close method appeared in version 1.15.0.

Attributes:

dtypestuple of dtype(s)

The data types of the values provided in value. This may be different from the operand data types if buffering is enabled. Valid only before the iterator is closed.

finishedbool

Whether the iteration over the operands is finished or not.

has_delayed_bufallocbool

If True, the iterator was created with the delay_bufalloc flag, and no reset() function was called on it yet.

has_indexbool

If True, the iterator was created with either the c_index or the f_index flag, and the property index can be used to retrieve it.

has_multi_indexbool

If True, the iterator was created with the multi_index flag, and the property multi_index can be used to retrieve it.

index

When the c_index or f_index flag was used, this property provides access to the index. Raises a ValueError if accessed and has_index is False.

iterationneedsapibool

Whether iteration requires access to the Python API, for example if one of the operands is an object array.

iterindexint

An index which matches the order of iteration.

itersizeint

Size of the iterator.

itviews

Structured view(s) of operands in memory, matching the reordered and optimized iterator access pattern. Valid only before the iterator is closed.

multi_index

When the multi_index flag was used, this property provides access to the index. Raises a ValueError if accessed accessed and has_multi_index is False.

ndimint

The dimensions of the iterator.

nopint

The number of iterator operands.

operandstuple of operand(s)

operands[_Slice_]

shapetuple of ints

Shape tuple, the shape of the iterator.

value

Value of operands at current iteration. Normally, this is a tuple of array scalars, but if the flag external_loop is used, it is a tuple of one dimensional arrays.

Methods