numpy.nditer

原文:https://docs.scipy.org/doc/numpy/reference/generated/numpy.nditer.html

译者:飞龙 UsyiyiCN

校对:(虚位以待)

class numpy.nditer[source]

有效的多维迭代器对象迭代数组。要开始使用此对象,请参阅introductory guide to array iteration

参数:

op:ndarray或array_like的序列

数组(s)迭代。

flags:str的序列,可选

控制迭代器行为的标志。

  • “buffered”在需要时启用缓冲。
  • “c_index”使C序索引被跟踪。
  • “f_index”导致跟踪Fortran顺序索引。
  • “multi_index”导致跟踪具有每迭代维度一个的多索引或索引的元组。
  • “common_dtype”使所有操作数被转换为公共数据类型,根据需要进行复制或缓冲。
  • “delay_bufalloc”延迟缓冲器的分配,直到进行reset()调用。允许在将值复制到缓冲区之前对“分配”操作数进行初始化。
  • “external_loop”使得给定的是具有多个值的一维数组,而不是零维数组。
  • “grow_inner”允许在使用“buffered”和“external_loop”时,使value数组大小大于缓冲区大小。
  • “ranged”允许迭代器被限制到iterindex值的子范围。
  • “refs_ok”启用引用类型的迭代,例如对象数组。
  • “reduce_ok”启用广播的“读写”操作数的迭代,也称为缩减操作数。
  • “zerosize_ok”允许itersize为零。

op_flags:str列表的列表,可选

这是每个操作数的标志列表。至少,必须指定“readonly”,“readwrite”或“writeonly”之一。

  • “readonly”表示只读操作数。
  • “readwrite”表示操作数将被读取和写入。
  • “writeonly”表示操作数将只被写入。
  • “no_broadcast”防止操作数被广播。
  • “contig”强制操作数数据是连续的。
  • “aligned”强制操作数数据对齐。
  • “nbo”强制操作数数据为原生字节顺序。
  • 如果需要,“copy”允许临时只读副本。
  • 如果需要,“updateifcopy”允许临时读写副本。
  • 如果在op参数中为“None”,则“allocate”将导致分配数组。
  • “no_subtype”防止“分配”操作数使用子类型。
  • “arraymask”表示该操作数是在使用'writemasked'标志设置写入操作数时用于选择元素的掩码。迭代器不强制这样做,但是当从缓冲区写回数组时,它只复制由该掩码指示的那些元素。
  • 'writemasked'表示只有选择的“arraymask”操作数为True的元素才会被写入。

op_dtypes:dtype(s)的dtype或tuple,可选

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

订单:{'C','F','A','K'},可选

控制迭代顺序。'C'表示C顺序,'F'表示Fortran顺序,'A'表示'F'顺序,如果所有数组都是Fortran连续的,'C'顺序否则,'K'表示接近数组元素出现的顺序在内存中。这也影响“分配”操作数的元素存储顺序,因为它们被分配为与迭代顺序兼容。默认值为“K”。

投射:{'no','equiv','safe','same_kind','unsafe'},可选

控制在进行复制或缓冲时可能发生的数据转换类型。不建议将此设置为“不安全”,因为它会对累积产生不利影响。

  • 'no'意味着不应该转换数据类型。
  • 'equiv'意味着只允许字节顺序改变。
  • “安全”意味着只允许保留值的转换。
  • 'same_kind'表示只允许一种类型中的安全类型转换,例如float64到float32。
  • “不安全”表示可以进行任何数据转换。

op_axes:ints列表列表,可选

如果提供,则是每个操作数的int或None列表。操作数的轴列表是从迭代器的维度到操作数的维度的映射。可以为条目放置值-1,从而将该维度视为“newaxis”。

itershape:ints的tuple,可选

迭代器的期望形状。这允许“分配”具有由op_ax映射的维度的操作数不对应于不同操作数的维度以获得对于该维度不等于1的值。

buffersize:int,可选

启用缓冲时,控制临时缓冲区的大小。对于默认值,设置为0。

笔记

nditer取代flatiternditer后的迭代器实现也由Numpy C API公开。

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

例子

下面是我们如何使用Python迭代器协议编写一个iter_add函数:

def iter_add_py(x, y, out=None):
    addop = np.add
    it = np.nditer([x, y, out], [],
                [['readonly'], ['readonly'], ['writeonly','allocate']])
    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']])

    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=[range(x.ndim)+[-1]*y.ndim,
                     [-1]*x.ndim+range(y.ndim),
                     None])

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

属性

dtypes (dtype(s)的元组)value中提供的值的数据类型。如果启用缓冲,这可能不同于操作数数据类型。
完成 (bool)操作数上的迭代是否完成。
has_delayed_bufalloc (bool)如果为True,迭代器使用“delay_bufalloc”标志创建,并且尚未调用reset()函数。
has_index (bool)如果为True,迭代器使用“c_index”或“f_index”标志创建,并且属性index可用于检索它。
has_multi_index (bool)如果为True,迭代器使用“multi_index”标志创建,并且属性multi_index可用于检索它。
指数: 当使用“c_index”或“f_index”标志时,此属性提供对索引的访问。如果访问时引发ValueError,并且has_index为False。
iterationneedsapi (bool)迭代是否需要访问Python API,例如,如果其中一个操作数是对象数组。
iterindex (int)匹配迭代次序的索引。
itersize (int)迭代器的大小。
itviews: 存储器中operands的结构化视图,匹配重新排序和优化的迭代器访问模式。
multi_index: 当使用“multi_index”标志时,此属性提供对索引的访问。如果访问访问并且has_multi_index为False,则引发ValueError。
ndim (int)迭代器的维度。
nop (int)迭代器操作数的数量。
操作数 (操作数的元组)要迭代的数组。
形状 (intup的tuple)形状元组,迭代器的形状。
值: 在当前迭代的operands的值。通常,这是一个数组的数组标量,但如果使用标志“external_loop”,它是一维数组的元组。

方法

copy() 获取迭代器的当前状态的副本。
debug_print() 打印nditer实例的当前状态并将调试信息输出到stdout。
enable_external_loop() 当在构造期间没有使用“external_loop”时,这是修改迭代器的行为,如同指定了标志。
iternext() 检查是否留下迭代,并执行单个内部迭代,而不返回结果。
next
remove_axis(i) 从迭代器中删除轴i
remove_multi_index() 当指定“multi_index”标志时,这将删除它,允许内部迭代结构进一步优化。
reset() 将迭代器重置为其初始状态。