取消NumPy数组操作中的标量。

3
我正在使用NumPy 1.7.1版本。 现在我遇到了一个我不理解的奇怪的取消:
>>> import numpy as np
>>> a = np.array([ 883,  931,  874], dtype=np.float32)

数学上来说,a+0.1-a应该等于0.1。 现在让我们计算这个表达式的值、绝对误差和相对误差:

>>> a+0.1-a
array([ 0.09997559,  0.09997559,  0.09997559], dtype=float32)
>>> (a+0.1-a)-0.1
array([ -2.44155526e-05,  -2.44155526e-05,  -2.44155526e-05], dtype=float32)
>>> ((a+0.1-a)-0.1) / 0.1
array([-0.00024416, -0.00024416, -0.00024416], dtype=float32)

第一个问题:这个绝对误差和相对误差都很高,这只是一种严重的“灾难性抵消”,对吗?
第二个问题:当我使用数组而不是标量时,NumPy能够以更高的精度计算,可以看到相对误差:
>>> a+np.array((0.1,)*3)-a
array([ 0.1,  0.1,  0.1])
>>> (a+np.array((0.1,)*3)-a)-0.1
array([  2.27318164e-14,   2.27318164e-14,   2.27318164e-14])

我猜这只是数字表示上的0.1

但是,如果使用标量而不是数组(例如a+0.1-a),为什么NumPy不能以相同的方式处理呢?

1个回答

4
如果你使用双精度(double precision),情况会有所改变。对于单精度(np.float32),你得到的结果是符合预期的:
a = np.array([ 883,  931,  874], dtype=np.float64)

a+0.1-a
# array([ 0.1,  0.1,  0.1])

((a+0.1-a)-0.1) / 0.1
# array([  2.27318164e-13,   2.27318164e-13,   2.27318164e-13])

在表达式中使用np.array((0.1,)*3)将所有内容转换为float64,这解释了第二个结果精度更高的原因。

1
好的,谢谢,我没有看到隐式的64位类型!我明白了,numpy不能在没有指示的情况下使用64位的a+0.1-a - roettm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接