需要在nditer()中设置标志吗?

问题描述 投票:0回答:1

如果我们想迭代存储在 nD 数组中的所有元素,我们可以使用 nditer() 但如果我们想设置要访问的元素的 dtype,那么我们还需要设置缓冲区,原因是什么为此?

例如::

import numpy as np
a = np.random.randint(1, 10, (10,))
for i in np.nditer(a,op_dtypes=['float']):
    print(i,end='\t')

上面的代码会给我错误。

错误声明:: 类型错误:迭代器操作数需要复制或缓冲,但复制或缓冲均未启用

要求我设置复制或缓冲标志,设置标志的目的是什么?缓冲和复制标志有什么作用?

              .              
python-3.x numpy data-science
1个回答
0
投票

您创建了一个整数数组:

In [16]: a = np.random.randint(1, 10, (10,))   
In [17]: a
Out[17]: array([5, 5, 8, 6, 5, 6, 4, 1, 8, 3])

您不需要

nditer
逐个元素地显示它,甚至不需要浮动形式:

In [18]: for i in a:
    ...:     print(i,end='\t')
    ...:     
5   5   8   6   5   6   4   1   8   3   

In [19]: for i in a.astype(float):
    ...:     print(i,end='\t')
    ...:     
5.0 5.0 8.0 6.0 5.0 6.0 4.0 1.0 8.0 3.0 

astype
我制作了浮动的临时副本。

我不明白你为什么要探索

nditer
。不要被它声称是“高效迭代器”的误导。我还没有看到它比简单的
for
更快。即使使用
nditer
,你仍然必须使用
for
。一般来说,你在循环中所做的事情会占用时间;迭代机制并不重要。无论
print()
包装如何,执行
for
10 次都会占用“x”时间。

In [20]: for i in np.nditer(a):
    ...:     print(i,end='\t')
    ...:     
5   5   8   6   5   6   4   1   8   3   

我不会尝试对这些替代方案进行计时,尤其是使用 io

print
函数。

按照文档链接中的示例进行操作:

https://numpy.org/doc/stable/reference/arrays.nditer.html#iteating-as-a-specific-data-type

In [23]: for i in np.nditer(a, op_flags=['readonly','copy'], op_dtypes=[float]):
    ...:     print(i, end='\t')
    ...:     
5.0 5.0 8.0 6.0 5.0 6.0 4.0 1.0 8.0 3.0 

显然,这些标志授予

nditer
相当于
astype(float)
的权限,无论是作为临时数组,还是即时缓冲。

np.nditer
最好用作在编译代码中使用
nditer
的测试场,如文档页面末尾所示,它使用
cython
。它对迭代和输出缓冲区的创建等提供了细粒度的控制。在编写正常的
numpy
代码时很少需要这种控制。

您将会遇到我们通常提倡使用预编译数组方法的问题。从全数组的角度思考,充分利用广播,

numpy
。尽量不要像时尚那样在列表中进行迭代,如果必须,请准备好将其移植到
ufuncs
cython
(如果您需要速度)。我还没有看到有经验的用户提出
numba
问题。
    

© www.soinside.com 2019 - 2024. All rights reserved.