nditer迭代和Python3打印格式的问题

时间:2015-05-07 08:06:03

标签: python python-3.x numpy

我正在使用

迭代numpy数组
for a, b in np.nditer([a_array, b_array]):
    print("{0:.3g},{1:.3g}".format(a, b))

但我收到TypeError: non-empty format string passed to object.__format__

如果我插入整数而不是ab

for a, b in np.nditer([a_array, b_array]):
    print("{0:.3g},{1:.3g}".format(2, 3))

它有效。

所以我想我的a_arrayb_array中的值存在问题。它们不被解释为正常数字吗?

如果我在nditer()中选择只读标记,我可以优化性能吗?

修改

一个例子

import numpy as np

a_array = np.array([])
b_array = np.array([])

number = float(input("Input number: "))

a_array = np.append(a_array, number)
b_array = np.append(b_array, number)

for a, b in np.nditer([a_array, b_array]):
    print("(a,W) = ({0:.3g},{1:.3g})".format(a, b))

1 个答案:

答案 0 :(得分:1)

nditer没有给你标量,它提供了1个元素数组:

In [6]: for a in np.nditer(np.arange(1)):
    print(type(a))
   ...:     
<class 'numpy.ndarray'>

In [7]: a
Out[7]: array(0)

所以普通的print(a)做得很好,但不是这些新的(v3)格式化表达式中的一个。旧样式有效:print('%.3f'%a)

item可用于从此数组中提取标量:

print("{:.3g}".format(a.item()))

'老式'迭代器可以工作(对{2个数组使用zip

for a in np.arange(3):
    print("{:g}".format(a))

通用格式规范也有效:print("{!s},{!r}".format(a,a))

In [59]: for a in np.nditer(np.arange(1)):
    print("{!s},{!r}".format(a,a))     
0,array(0)

基本上g和其他数字格式规范不适用于nditer的迭代变量,因为它们是数组,而不是标量。我猜这是np.__format__方法的一个问题。它只是使用继承的object版本。

ps - 给一些样本数组可能已经避免了负面投票,即使这个细节不重要。

默认情况下,

nditer会生成readonly个值。因此设置标志不会改变它们(对标量)或提高效率:

In [258]: for a in np.nditer(A):a[...]=1
...
ValueError: assignment destination is read-only

指定读/写标志在这样的上下文中很有用:

In [268]: A=np.array([0,1,2,3])
In [269]: B=np.empty((4,))
In [270]: for a,b in np.nditer([A,B],op_flags=[['readonly'],['readwrite']]):
    b[...] = a*2
   .....:     
In [271]: B
Out[271]: array([ 0.,  2.,  4.,  6.])

对于您的样本,'for zip'有效,而且速度更快。如果您需要其额外功能,请预留nditer

In [274]: for a,b in zip(a_array, b_array):
   .....:     print("(a,W) = ({0:.3g},{1:.3g})".format(a, b))
(a,W) = (20,20)