numpy.nditer #
- 类 numpy. nditer ( op , flags = None , op_flags = None , op_dtypes = None , order = 'K' , casting = 'safe' , op_axes = None , itershape = None , buffersize = 0 ) [来源] #
用于迭代数组的高效多维迭代器对象。要开始使用此对象,请参阅 数组迭代介绍指南。
- 参数:
- op ndarray 或 array_like 序列
要迭代的数组。
- str 的标志序列,可选
控制迭代器行为的标志。
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
为零。
- op_flags str 列表列表,可选
这是每个操作数的标志列表。至少 必须指定
readonly
、readwrite
或之一。writeonly
readonly
表示该操作数只能被读取。readwrite
指示将读取和写入操作数。writeonly
表示该操作数只会被写入。no_broadcast
防止操作数被广播。contig
强制操作数数据连续。aligned
强制操作数数据对齐。nbo
强制操作数数据采用本机字节顺序。copy
如果需要,允许临时只读副本。updateifcopy
如果需要,允许临时读写副本。allocate
如果参数中为 None ,则导致分配数组op
。no_subtype
防止allocate
操作数使用子类型。arraymask
指示该操作数是在写入设置有“writemasked”标志的操作数时用于选择元素的掩码。迭代器不强制执行此操作,但当从缓冲区写回数组时,它仅复制此掩码指示的那些元素。writemasked
表示只有所选arraymask
操作数为 True 的元素才会被写入。overlap_assume_elementwise
可用于标记仅按迭代器顺序访问的操作数,以允许在copy_if_overlap
存在时进行不太保守的复制。
- op_dtypes dtype 或 dtype 的元组,可选
操作数所需的数据类型。如果启用复制或缓冲,数据将与其原始类型相互转换。
- 顺序{'C', 'F', 'A', 'K'},可选
控制迭代顺序。 'C' 表示 C 顺序,'F' 表示 Fortran 顺序,'A' 表示 'F' 顺序(如果所有数组都是 Fortran 连续的),'C' 顺序,否则,'K' 表示尽可能接近数组元素出现的顺序尽可能在记忆中。这也会影响操作数的元素内存顺序
allocate
,因为它们被分配为与迭代顺序兼容。默认为“K”。- 强制转换{'no', 'equiv', 'safe', 'same_kind', 'unsafe'},可选
控制进行复制或缓冲时可能发生的数据转换类型。不建议将其设置为“不安全”,因为它会对累积产生不利影响。
“no”意味着根本不应该转换数据类型。
'equiv' 表示仅允许字节顺序更改。
“安全”意味着只允许可以保留值的强制转换。
“same_kind”表示仅允许安全强制转换或某种类型内的强制转换,例如从 float64 到 float32。
“不安全”意味着可以进行任何数据转换。
- op_axes整数列表列表,可选
如果提供,则为每个操作数的整数列表或无。操作数的轴列表是从迭代器的维度到操作数的维度的映射。可以为条目放置值 -1,导致该维度被视为
newaxis
。- itershape整数元组,可选
迭代器所需的形状。这允许具有
allocate
由 op_axes 映射的维度的操作数不对应于不同操作数的维度,以获得该维度不等于 1 的值。- buffersize int,可选
启用缓冲后,控制临时缓冲区的大小。默认值设置为 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])
如果使用操作数标志
"writeonly"
或 ,操作数可以通过WRITEBACKIFCOPY"readwrite"
标志查看原始数据 。在这种情况下,必须用作上下文管理器,或者必须在使用结果之前调用该方法。临时数据将在函数调用时写回原始数据,但不会在此之前: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版本中。- 属性:
- dtypes dtype 的元组
中提供的值的数据类型
value
。如果启用缓冲,这可能与操作数数据类型不同。仅在迭代器关闭之前有效。- 完成布尔值
操作数的迭代是否完成。
- has_delayed_bufalloc布尔值
如果为 True,则迭代器是使用该
delay_bufalloc
标志创建的,并且尚未对其调用 reset() 函数。- has_index布尔值
如果为 True,则迭代器是使用
c_index
或标志创建的,并且可以使用f_index
该属性来检索它。index
- has_multi_index布尔值
如果为 True,则迭代器是使用该
multi_index
标志创建的,并且该属性multi_index
可用于检索它。- 指数
当使用
c_index
or标志时,此属性提供对索引的访问。f_index
如果访问且为 False,则引发 ValueErrorhas_index
。- 迭代需要sapi bool
迭代是否需要访问 Python API,例如操作数之一是否是对象数组。
- 迭代索引int
与迭代顺序匹配的索引。
- 迭代大小int
迭代器的大小。
- 其观点
内存中的结构化视图
operands
,匹配重新排序和优化的迭代器访问模式。仅在迭代器关闭之前有效。- 多索引
multi_index
当使用该标志时,此属性提供对索引的访问。如果访问且为 False,则引发 ValueErrorhas_multi_index
。- 恩迪姆整数
迭代器的维度。
- nop整数
迭代器操作数的数量。
operands
操作数元组操作数[切片]
- 整数的形状元组
形状元组,迭代器的形状。
- 价值
operands
当前迭代时的值。通常,这是一个数组标量的元组,但如果external_loop
使用该标志,则它是一个一维数组的元组。
方法
close
()解析可写操作数中的所有写回语义。
copy
()获取当前状态的迭代器的副本。
将实例的当前状态
nditer
和调试信息打印到标准输出。当构造期间未使用“external_loop”但需要时,这会修改迭代器,使其行为就像指定了该标志一样。
iternext
()检查是否剩余迭代,并执行一次内部迭代而不返回结果。
remove_axis
(我, /)从迭代器中删除轴i 。
当指定“multi_index”标志时,会将其删除,从而允许进一步优化内部迭代结构。
reset
()将迭代器重置为其初始状态。