正如之前的答案所述,这是编程语言中常见的浮点数算术问题。 您应该注意永远不要对 float
类型应用精确相等性。
当您进行此类比较时,可以使用基于给定公差(阈值)的函数进行比较。 如果数字足够接近,则应将它们视为数字相等。 像这样:
def isequal_float(x1,x2, tol=10**(-8)):
"""Returns the results of floating point equality, according to a tolerance."""
return abs(x1 - x2)<tol
会起作用。如果我没记错的话,精度取决于您使用的语言以及float
类型是单精度还是双精度。
使用这样的函数可以轻松比较计算结果,例如在numpy
中。让我们以以下示例为例,其中对具有连续变量的数据集计算相关矩阵,使用两种方法: pandas
方法pd.DataFrame.corr()
和numpy
函数np.corrcoef()
:
import numpy as np
import seaborn as sns
iris = sns.load_dataset('iris')
iris.drop('species', axis = 1, inplace=True)
cor1 = iris.corr().to_numpy()
cor2 = np.corrcoef(iris.transpose())
print(cor1)
print(cor2)
结果看起来相似:
[[ 1. -0.11756978 0.87175378 0.81794113]
[-0.11756978 1. -0.4284401 -0.36612593]
[ 0.87175378 -0.4284401 1. 0.96286543]
[ 0.81794113 -0.36612593 0.96286543 1. ]]
[[ 1. -0.11756978 0.87175378 0.81794113]
[-0.11756978 1. -0.4284401 -0.36612593]
[ 0.87175378 -0.4284401 1. 0.96286543]
[ 0.81794113 -0.36612593 0.96286543 1. ]]
但它们的精确相等性结果并不相同。这些运算符:
print(cor1 == cor2)
print(np.equal(cor1, cor2))
将会逐元素产生大多数False
结果:
[[ True False False False]
[False False False False]
[False False False False]
[False False False True]]
同样地,
np.array_equal(cor1, cor2)
也会产生
False
。然而,自定义函数提供了您想要的比较:
out = [isequal_float(i,j) for i,j in zip(cor1.reshape(16, ), cor2.reshape(16, ))]
print(out)
[True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True]
注意:numpy
包含 .allclose()
函数,可在 numpy 数组中执行浮点元素逐个比较。
print(np.allclose(cor1, cor2))
>>>True