如果我们想迭代存储在 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')
上面的代码会给我错误。
错误声明:: 类型错误:迭代器操作数需要复制或缓冲,但复制或缓冲均未启用
要求我设置复制或缓冲标志,设置标志的目的是什么?缓冲和复制标志有什么作用?
.
您创建了一个整数数组:
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
问题。