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

zfycwa2u  于 5个月前  发布在  其他
关注(0)|答案(1)|浏览(53)

如果我们想把所有的元素存储在一个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')

字符串
上面的代码将给予我的错误。
错误语句::TypeError:迭代器操作数需要复制或缓冲,但复制和缓冲都未启用
它要求我把标志设置为复制或缓冲,设置标志的目的是什么,缓冲和复制标志做什么?

.

vom3gejh

vom3gejh1#

创建一个整数数组:

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来逐个元素显示它,甚至不需要以float形式显示:

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。通常是你在循环中做的事情占用了时间;迭代机制并不重要。不管for Package 器如何,执行print() 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函数时。
以下是doc链接中的示例:
https://numpy.org/doc/stable/reference/arrays.nditer.html#iterating-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问题。从整个数组操作的Angular 考虑,并充分利用广播和ufuncs。尽量不要像时尚一样在列表中播放,如果你必须这样做,如果你需要速度的话,准备把它移植到cythonnumba上。我还没有看到有经验的用户提出nditer的问题。
当你在for i in a:...中进行编译时,i将是一个numpy scalar,在这种情况下是np.int32。使用nditeri将是一个0 d数组(具有相同的dtype)。区别是微妙的,但可能是重要的。在我看来,nditer通常会增加比需要更多的复杂性。

相关问题