我有一个由python numpy生成的间隔范围。这些值是预期的,但是当数组转换为列表时,值与数组中的值不同。
numpy.linspace(0.3,0.7,5)
array([ 0.3, 0.4, 0.5, 0.6, 0.7])
numpy.linspace(0.3,0.7,5).tolist()
[0.3, 0.39999999999999997, 0.5, 0.6, 0.7]
list(numpy.linspace(0.3,0.7,5))
[0.29999999999999999,0.39999999999999997,0.5,0.59999999999999998,
0.69999999999999996]
为什么numpy表现得像这样?无论如何要保持列表中的值与数组相同而不使用另一个循环来舍入列表中的值吗?
答案 0 :(得分:4)
恰好是因为每种类型的数据类型和相应的__repr__
实现:
l = numpy.linspace(0.3,0.7,5).tolist()
[type(x) for x in l]
[float, float, float, float, float]
在第一种情况下,tolist
将每个np.float
对象转换为python float
对象,其__repr__
实现根据{{3}自动截断浮点数。 }。 OTOH:
l = list(numpy.linspace(0.3,0.7,5))
[type(x) for x in l]
[numpy.float64, numpy.float64, numpy.float64, numpy.float64, numpy.float64]
只是在数组周围调用list
不会将列表元素转换为float
,但保留其原始np.float
类型,它们具有不同的表示形式。请记住,第二种情况下的浮点表示是它们在内存中实际表示的方式:
import decimal
decimal.Decimal(0.3)
Decimal('0.299999999999999988897769753748434595763683319091796875')
因为许多浮点数没有精确的位表示。有关详细信息,请参阅我们心爱的规范Gay algorithm。