我正在尝试在Numpy(mean
和interp
)中执行一些不同的操作,并且对于这两个操作,我在不同时间得到结果2.77555756156e-17
,通常是在我&# 39;我期待零。 即使尝试使用 array[array < 0.0] = 0.0
过滤掉这些也无法删除值。
我认为存在导致此问题的某种基础数据类型或环境错误。数据应全部浮动。
编辑:已经有人指出我只过滤了-2.77555756156e-17的值,但仍看到正2.77555756156e-17。问题的关键是在执行简单函数时可能导致这些古怪值的原因,例如在0-10之间插值,并在相同范围内取浮点数,我该如何避免它无需在每个语句后显式过滤数组。
答案 0 :(得分:2)
你正在遇到数值精度,这是数值计算的一个重要主题;当您使用浮点数进行任何计算时,您可能会遇到像您在此处发布的那样微小的值。发生的事情是,您的计算导致的值无法用浮点数表示。
浮点数用固定数量的信息表示(在Python中,此数量默认为64位)。您可以阅读更多有关如何在非常好的Floating point Wikipedia page上编码信息的信息。简而言之,您在计算平均值的过程中执行的某些计算会产生无法精确表达的中间值。
这不是numpy的属性(它甚至不是Python的属性);它真的是计算机本身的属性。你可以通过在repl:
中玩游戏来看到这是普通的Python>>> repr(3.0)
'3.0'
>>> repr(3.0 + 1e-10)
'3.0000000001'
>>> repr(3.0 + 1e-18)
'3.0'
对于最后一个结果,您会期望3.000000000000000001
,但该数字不能用64位浮点数表示,因此计算机使用最接近的近似值,在本例中仅为{{ 1}}。如果您尝试平均以下数字列表:
3.0
根据您对它们求和的顺序,您可以得到[3., -3., 1e-18]
,这是“正确”答案,或者为零。你的情况有点奇怪;你希望取消的两个数字并没有完全取消。
当你处理浮点数学时,这只是生活中的一个事实。解决它的常用方法是完全避开等号,只执行“数值容忍比较”,这意味着与...相等。所以这个检查:
1e-18 / 3.
将成为此检查:
a == b
对于一些容忍量。容差取决于您对输入的了解以及计算机的精度;如果您使用的是64位计算机,则希望它至少是您将使用的最大数量的abs(a - b) < TOLERANCE
倍。例如,如果您要使用的最大输入大约为100,那么使用1e-10
的容差是合理的。
答案 1 :(得分:1)
您可以将值舍入为15位数:
a = a.round(15)
现在,数组a
应显示0.0
个值。
示例:
>>> a = np.array([2.77555756156e-17])
>>> a.round(15)
array([ 0.])
答案 2 :(得分:1)
这很可能是浮点算术错误的结果。例如:
In [3]: 0.1 + 0.2 - 0.3
Out[3]: 5.551115123125783e-17
不是你所期望的? Numpy有一个内置的isclose()
方法可以处理这些事情。此外,您可以使用
eps = np.finfo(np.float).eps
所以,也许这样的事情也可以起作用:
a = np.array([[-1e-17, 1.0], [1e-16, 1.0]])
a[np.abs(a) <= eps] = 0.0