在元组列表中忽略numpy set_printoptions精度

时间:2017-12-04 16:39:43

标签: numpy python-3.4 precision

(Windows 7,Python 3.4.5 | Anaconda 2.2.0(64位)|(默认,2016年7月5日,14:53:07)[MSC v.1600 64 bit(AMD64)])

我试图通过使用np.set_printoptions整齐地打印一些数据(precision =并且它似乎被忽略了。为什么?

import numpy as np
np.set_printoptions(precision=4)

a=[[1,15.02],
[2,14.38],
[3,14.60]]

b=np.array(a)
print(b)
at=b.T
l=list(zip(at[0],at[1]))
print(l)

输出:

[[  1.    15.02]
 [  2.    14.38]
 [  3.    14.6 ]]
[(1.0, 15.02), (2.0, 14.380000000000001), (3.0, 14.6)]

2 个答案:

答案 0 :(得分:0)

浮动问题:

In [118]:ref=decimal.Decimal('14.380000000000000000000000000000000000000000000000')

In [119]: decimal.Decimal(14.38)
Out[119]: Decimal('14.3800000000000007815970093361102044582366943359375')

In [120]: decimal.Decimal(14.38)-ref
Out[120]: Decimal('7.815970093361102044582366943E-16')

In [121]: decimal.Decimal(14.38-2**-50)-ref
Out[121]: Decimal('-9.947598300641402602195739746E-16')

这表明14.380000000000001是最佳的float64近似值14.38。

要解决这个问题,你可以降级np.float32:

In [140]:tuple(zip(*np.array(a).T.astype(np.float32)))
Out[140]: ((1.0, 15.02), (2.0, 14.38), (3.0, 14.6))

答案 1 :(得分:0)

In [34]: a
Out[34]: [[1, 15.02], [2, 14.38], [3, 14.6]]
In [35]: b=np.array(a, dtype=float).T
In [36]: b
Out[36]: 
array([[  1.  ,   2.  ,   3.  ],
       [ 15.02,  14.38,  14.6 ]])
In [37]: list(zip(*b))
Out[37]: [(1.0, 15.02), (2.0, 14.380000000000001), (3.0, 14.6)]

但是,如果我首先通过btolist

In [38]: list(zip(*b.tolist()))
Out[38]: [(1.0, 15.02), (2.0, 14.38), (3.0, 14.6)]

在第一种情况下,元组的元素仍然具有np.float64包装,而tolist将它们全部提取为本机Python数字:

In [39]: type(list(zip(*b))[1][1])
Out[39]: numpy.float64
In [40]: type(list(zip(*b.tolist()))[1][1])
Out[40]: float

item是另一种提取原生数字的方法:

In [41]: list(zip(*b))[1][1]
Out[41]: 14.380000000000001
In [42]: list(zip(*b))[1][1].item()
Out[42]: 14.38

我不能说为什么setprintoptions不适用于np.float64,但适用于np.array

作为一般规则,如果要将数组及其所有值转换为本机Python列表,最好使用tolist()。列表和zip等操作是不够的。它们迭代数组的第一维,但不递归转换元素:

部分转换:

In [43]: list(b)
Out[43]: [array([ 1.,  2.,  3.]), array([ 15.02,  14.38,  14.6 ])]
In [44]: list(b[1])
Out[44]: [15.02, 14.380000000000001, 14.6]

完全转换:

In [45]: b.tolist()
Out[45]: [[1.0, 2.0, 3.0], [15.02, 14.38, 14.6]]

显然float64的格式化程序显示所有精度,无论set_printoptions值如何:

In [58]: 14.380000000000001
Out[58]: 14.38
In [59]: np.array(14.380000000000001)
Out[59]: array(14.38)
In [60]: np.float64(14.380000000000001)
Out[60]: 14.380000000000001
In [61]: np.float32(14.380000000000001)
Out[61]: 14.38

np.float64(...)对象在很多方面类似于单个项目数组,但在细微方面有所不同。通常我们不会直接创建这样的对象。