NumPy参考 >例行程序 >Indexing routines > numpy.nditer
numpy.
nditer
[源代码] ¶有效的多维迭代器对象,可以遍历数组。要开始使用此对象,请参阅 数组迭代入门指南。
要迭代的数组。
用于控制迭代器行为的标志。
buffered
需要时启用缓冲。
c_index
使C顺序索引被跟踪。
f_index
导致跟踪Fortran顺序索引。
multi_index
导致跟踪一个多索引或每个迭代维度一个的索引元组。
common_dtype
使所有操作数都转换为通用数据类型,并根据需要进行复制或缓冲。
copy_if_overlap
使迭代器确定读取操作数是否与写入操作数重叠,并根据需要制作临时副本以避免重叠。在某些情况下,可能会出现误报(不需要复制)的情况。
delay_bufalloc
延迟缓冲区的分配,直到调用reset()为止。允许allocate
在将操作数的值复制到缓冲区之前进行初始化。
external_loop
导致values
给定的是具有多个值的一维数组,而不是零维数组。
grow_inner
允许value
同时使用buffered
和
时使数组大小大于缓冲区大小external_loop
。
ranged
允许将迭代器限制在iterindex值的子范围内。
refs_ok
启用引用类型的迭代,例如对象数组。
reduce_ok
启用readwrite
广播的操作数的迭代,也称为归约操作数。
zerosize_ok
允许itersize
为零。
这是每个操作数的标志的列表。至少,一个
readonly
,readwrite
或者writeonly
必须指定。
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
存在时允许较少的保守复制。
所需的操作数的数据类型。如果启用了复制或缓冲,则数据将转换为原始类型或从原始类型转换。
控制迭代顺序。'C'表示C顺序,'F'表示Fortran顺序,'A'表示'F'顺序(如果所有数组都是连续的),否则'C'顺序,'K'表示与数组元素出现的顺序接近在内存中。这也影响allocate
操作数的元素存储顺序,因为它们被分配为与迭代顺序兼容。默认值为“ K”。
控制在进行复制或缓冲时可能发生的数据类型转换。不建议将其设置为“不安全”,因为这可能会对累积产生不利影响。
“否”表示完全不应该转换数据类型。
“ equiv”表示仅允许字节顺序更改。
“安全”表示只允许保留值的强制类型转换。
“ same_kind”表示仅允许安全类型转换或同一类型内的类型转换,例如float64到float32。
“不安全”表示可能会进行任何数据转换。
如果提供,则为每个操作数的整数或无列表。操作数的轴列表是从迭代器的尺寸到操作数的尺寸的映射。可以将值-1放入条目中,从而将该维度视为newaxis
。
迭代器的所需形状。这允许allocate
操作数具有由op_axes映射的维,该操作数与另一个操作数的维不对应,因此该维的值不等于1。
启用缓冲后,控制临时缓冲区的大小。设置为0作为默认值。
笔记
nditer
取代flatiter
。nditer
NumPy C API也公开了后面的迭代器实现
。
Python公开提供了两个迭代接口,一个遵循Python迭代器协议,另一个反映C风格的do-while模式。在大多数情况下,本机Python方法更好,但是如果您需要迭代器的坐标或索引,请使用C样式模式。
例子
这是我们iter_add
使用Python迭代器协议编写函数的方式:
>>> 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])
如果使用操作数标志“只写”或“读写”,则操作数可能是带有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.writebackifcopy为True,则退出迭代器将切断x和a之间的连接,写给x将不再写给a。如果写回语义不处于活动状态,则 x.data仍将指向a.data的某个部分,而写一个将影响另一个。
上下文管理和close
方法出现在1.15.0版中。
中提供的值的数据类型value
。如果启用了缓冲,这可能与操作数数据类型不同。仅在关闭迭代器之前有效。
操作数的迭代是否完成。
如果为True,则使用该delay_bufalloc
标志创建迭代器,并且尚未对其调用reset()函数。
如果为True,则使用c_index
或f_index
标志创建迭代器,并且该属性index
可用于检索它。
如果为True,则使用multi_index
标志创建迭代器,并且multi_index
可以使用该属性来检索它。
使用c_index
or f_index
标志时,此属性提供对索引的访问。如果被访问,has_index
则引发ValueError,并且为False。
迭代是否需要访问Python API,例如,如果操作数之一是对象数组。
与迭代顺序匹配的索引。
迭代器的大小。
operands
内存中的结构化视图,与重新排序和优化的迭代器访问模式匹配。仅在关闭迭代器之前有效。
使用该multi_index
标志时,此属性提供对索引的访问。如果被访问,has_multi_index
则引发ValueError,并且为False。
迭代器的尺寸。
迭代器操作数的数量。
operands
操作数元组操作数[ Slice ]
形状元组,迭代器的形状。
operands
当前迭代的值。通常,这是数组标量的元组,但是如果使用标志external_loop
,则它是一维数组的元组。
方法
|
解决可写操作数中的所有写回语义。 |
|
获取当前状态的迭代器的副本。 |
打印 |
|
如果在构造过程中未使用“ external_loop”,但在需要使用“ external_loop”时,这将修改迭代器,使其表现得好像指定了标志。 |
|
|
检查是否还剩下迭代,并执行一次内部迭代,而不返回结果。 |
|
从迭代器中删除轴i。 |
指定“ multi_index”标志后,将其删除,从而可以进一步优化内部迭代结构。 |
|
|
将迭代器重置为其初始状态。 |