numpy.nditer#

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

高效的多维迭代器对象,用于迭代数组.要开始使用此对象,请参阅 数组迭代入门指南.

参数:
opndarray 或 array_like 的序列

要迭代的数组.

flags字符串序列,可选

控制迭代器行为的标志.

  • buffered 在需要时启用缓冲.

  • c_index 导致一个 C 顺序索引被跟踪.

  • f_index 导致跟踪一个 Fortran 顺序索引.

  • multi_index 导致一个多索引,或者一个每迭代维度一个索引的索引元组,被跟踪.

  • common_dtype 导致所有操作数被转换为通用数据类型,必要时进行复制或缓冲.

  • copy_if_overlap 导致迭代器确定读取操作数是否与写入操作数重叠,并在必要时创建临时副本以避免重叠.在某些情况下可能会出现误报(不必要的复制).

  • delay_bufalloc 延迟缓冲区的分配,直到调用 reset() 为止.允许在将 allocate 操作数的值复制到缓冲区之前对其进行初始化.

  • external_loop 导致给出的 values 是一维数组,包含多个值,而不是零维数组.

  • grow_inner 允许在同时使用 bufferedexternal_loop 时,使 value 数组的大小大于缓冲区大小.

  • ranged 允许迭代器被限制在 iterindex 值的子范围内.

  • refs_ok 启用对引用类型的迭代,例如对象数组.

  • reduce_ok 启用对被广播的 readwrite 操作数的迭代,也称为归约操作数.

  • zerosize_ok 允许 itersize 为零.

op_flagslist of list of str, 可选

这是一个每个操作数的标志列表.至少必须指定 readonlyreadwritewriteonly 中的一个.

  • readonly 表示操作数只会被读取.

  • readwrite 表示操作数将被读取和写入.

  • writeonly 表示操作数只会被写入.

  • no_broadcast 防止操作数被广播.

  • contig 强制操作数数据连续.

  • aligned 强制操作数数据对齐.

  • nbo 强制操作数数据为本地字节顺序.

  • copy 允许在需要时创建一个临时的只读副本.

  • updateifcopy 允许在需要时创建一个临时的可读写副本.

  • allocate 如果在 op 参数中为 None,则会导致数组被分配.

  • no_subtype 防止 allocate 操作数使用子类型.

  • arraymask 表示当写入带有 ‘writemasked’ 标志的运算对象时,该运算对象是用于选择元素的掩码.迭代器不会强制执行此操作,但在从缓冲区写回数组时,它仅复制此掩码指示的那些元素.

  • writemasked 表示只有选定的 arraymask 操作数为 True 的元素才会被写入.

  • overlap_assume_elementwise 可以用来标记仅按迭代器顺序访问的操作数,以允许在存在 copy_if_overlap 时进行更少保守的复制.

op_dtypesdtype 或 dtype 的元组,可选

操作数的所需数据类型.如果启用了复制或缓冲,数据将被转换为其原始类型或从其原始类型转换.

order{‘C’, ‘F’, ‘A’, ‘K’}, 可选

控制迭代顺序.’C’ 表示 C 顺序,’F’ 表示 Fortran 顺序,’A’ 表示如果所有数组都是 Fortran 连续的,则为 ‘F’ 顺序,否则为 ‘C’ 顺序,’K’ 表示尽可能接近数组元素在内存中出现的顺序.这也会影响 allocate 操作数的元素内存顺序,因为它们被分配为与迭代顺序兼容.默认是 ‘K’.

casting{‘no’, ‘equiv’, ‘safe’, ‘same_kind’, ‘unsafe’}, 可选

控制在进行复制或缓冲时可能发生的数据转换类型.将其设置为 ‘不安全’ 是不推荐的,因为它可能会对累积产生不利影响.

  • ‘no’ 意味着数据类型根本不应该被转换.

  • ‘equiv’ 意味着只允许字节顺序的改变.

  • ‘safe’ 意味着只允许可以保留值的转换.

  • ‘same_kind’ 意味着只允许安全转换或同类转换,例如 float64 到 float32.

  • ‘unsafe’ 意味着任何数据转换都可能进行.

op_axeslist of list of ints, 可选

如果提供,是对每个操作数的整数列表或 None.操作数的轴列表是从迭代器的维度到操作数的维度的映射.可以为条目放置 -1 的值,使该维度被视为 newaxis.

itershape整数的元组,可选

迭代器的期望形状.这允许 allocate 操作数的一个维度通过 op_axes 映射到不同操作数的一个维度,以获得该维度不等于 1 的值.

buffersizeint, 可选

当启用缓冲时,控制临时缓冲区的大小.设置为0以使用默认值.

备注

nditer 取代了 flatiter. nditer 背后的迭代器实现也通过 NumPy C API 暴露出来.

Python 暴露了两种迭代接口,一种遵循 Python 迭代器协议,另一种镜像 C 风格的 do-while 模式.在大多数情况下,原生 Python 方法更好,但如果你需要迭代器的坐标或索引,请使用 C 风格模式.

示例

以下是我们如何使用 Python 迭代器协议编写 iter_add 函数的方法:

>>> import numpy as np
>>> 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]

这里是相同的函数,但遵循C语言风格模式:

>>> 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]

这是一个外积函数的示例:

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

这是一个像”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])

如果使用了操作数标志 "writeonly""readwrite",操作数可能是带有 WRITEBACKIFCOPY 标志的原始数据的视图.在这种情况下,必须将 nditer 用作上下文管理器,或者在使用结果之前调用 nditer.close 方法.临时数据将在调用 __exit__ 函数时写回原始数据,但不会在此之前写回:

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

需要注意的是,一旦迭代器退出,悬空引用(如示例中的 x)可能与原始数据 a 共享数据,也可能不共享.如果启用了回写语义,即如果 x.base.flags.writebackifcopyTrue,那么退出迭代器将切断 xa 之间的连接,写入 x 将不再写入 a.如果未启用回写语义,那么 x.data 仍将指向 a.data 的某个部分,写入一个将影响另一个.

上下文管理和 close 方法出现在版本 1.15.0.

属性:
dtypesdtype(s) 的元组

value 中提供的值的数据类型.如果启用了缓冲,这可能与操作数数据类型不同.仅在迭代器关闭之前有效.

finishedbool

操作数的迭代是否完成.

has_delayed_bufallocbool

如果为真,迭代器是使用 delay_bufalloc 标志创建的,并且尚未在其上调用 reset() 函数.

has_indexbool

如果为真,迭代器是使用 c_indexf_index 标志创建的,并且可以使用属性 index 来检索它.

has_multi_indexbool

如果为真,迭代器是使用 multi_index 标志创建的,并且可以使用属性 multi_index 来检索它.

index

当使用了 c_indexf_index 标志时,此属性提供对索引的访问.如果访问时 has_index 为 False,则会引发 ValueError.

iterationneedsapibool

是否迭代需要访问 Python API,例如如果其中一个操作数是对象数组.

iterindexint

一个与迭代顺序匹配的索引.

itersizeint

迭代器的大小.

itviews

内存中 操作数 的结构化视图,匹配重新排序和优化的迭代器访问模式.仅在迭代器关闭之前有效.

multi_index

当使用了 multi_index 标志时,此属性提供对索引的访问.如果访问时 has_multi_index 为 False,则引发 ValueError.

ndimint

迭代器的维度.

nopint

迭代器操作数的数量.

operands操作数的元组

操作数[Slice]

shapeints 的元组

形状元组,迭代器的形状.

value

当前迭代的 operands 值.通常,这是一个数组标量的元组,但如果使用了 external_loop 标志,它是一个一维数组的元组.

方法

close()

解析所有可写操作数中的写回语义.

copy()

获取迭代器在其当前状态的副本.

debug_print()

nditer 实例的当前状态和调试信息打印到标准输出.

enable_external_loop()

当在构建过程中没有使用"external_loop”,但希望使用时,这会修改迭代器的行为,就像指定了该标志一样.

iternext()

检查是否还有迭代次数,并执行一次内部迭代而不返回结果.

remove_axis(i, /)

从迭代器中移除轴 i.

remove_multi_index()

当指定了"multi_index”标志时,这会移除它,允许内部迭代结构进一步优化.

reset()

将迭代器重置为其初始状态.