我有一个 numpy 数组 x
,它是根据一个复杂的方程计算出来的:
x = (QT-m_μ_Q*M_T)/(m*σ_Q*Σ_T)
print(x)
print(x[0], x[1], x[2])
print(1.0-x)
打印:
[ 1. 1. 1.]
1.0 1.0 1.0
[ -2.22044605e-16 3.33066907e-16 -4.44089210e-16]
请注意,最后一行打印出一些很小且非常接近零但非零的内容。我的下一步是取每个值的平方根,因此它不应该包含负值。
显式地从包含 1 的数组开始:
y = np.array([1., 1., 1.])
print(y)
print(y[0], y[1], y[2])
print(1.0-y)
产生正确的结果,所以我不确定有什么区别:
[ 1. 1. 1.]
1.0 1.0 1.0
[ 0. 0. 0.]
最佳答案
简而言之,x
中的值并不是真正的 1。那是因为您对不精确的值进行运算(您使用的公式)(浮点不精确,另请参阅 Is floating point math broken? )。
但是默认精度不显示差异。但是,当您减去一个时,您会得到通常所说的灾难性取消(例如,参见 Wikipedia 或 Why is 'catastrophic cancellation' called so? )。
例如:
>>> import numpy as np
>>> np.array([1, 1.00000000000002, 1.000000000000002, 1.0000000000000002])
array([ 1., 1., 1., 1.])
>>> 1 - np.array([1, 1.00000000000002, 1.000000000000002, 1.0000000000000002])
array([ 0.00000000e+00, -1.99840144e-14, -1.99840144e-15, -2.22044605e-16])
通常有两种方法可以解决此问题:
- 使用避免灾难性取消的公式(可能不可能)。但是,在您的情况下,您可以尝试
sqrt((y-x)/y)
而不是sqrt(1-x/y)
- 只需插入x 的正确表达式
(QT-m_μ_Q*M_T
) 和y
(m*σ_Q*Σ_T
)。从数学上讲,两者是等效的,但由于 float 学,它们可能给出不同的结果。 - 对结果进行四舍五入和/或将负值设置为零。
关于python - Numpy 减法精度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42564147/