数组 -> 字符串 -> 数组转换的舍入错误

Rounding error from array -> string -> array conversion

我正在尝试通过水平连接 4 列中的数据来创建一个数组,如下所示:

col1=numpy.arange(191.25,196.275,.001)[:, numpy.newaxis]
nrows=col1.shape[0]

col2=numpy.zeros((nrows,1),dtype=numpy.int)
col3=numpy.zeros((nrows,1),dtype=numpy.int)
col4=numpy.ones((nrows,1),dtype=numpy.int)

a=numpy.hstack((col1,col2,col3,col4))

然后我把它转换成字符串:

a_str = '\n'.join('\t'.join('%0.3f' %x for x in y) for y in a)+'\n'

并将其转换回二维 numpy 数组:

a2=numpy.array(filter(None,re.split('[\n\t]+',a_str)),dtype=float).reshape(-1,4)

但现在当我得到 FALSE 时,当我比较时:

a[-1,0]==a2[-1,0]

当我查看各个值时,我看到:

a[-1,0]=196.27500000002399
a2[-1,0]=196.27500000000001

是否存在与从数组转换为字符串并返回相关的浮动 point/rounding 错误(a2 实际上比 a 更接近所需值 196.275)?我该怎么做才能使值相等?我的怀疑是,当我最初通过迭代加法生成 col1 来产生错误时,会在后面的数组索引中混合错误。这是否意味着我应该改为显式枚举 col1 的值,或者是否有解决方法?

根本上没有真正的解决方案。一般来说,有限十进制字符串和有限二进制表示没有精确的等价物。在此类转换中会产生舍入误差,并且必须使用 np.allclose 之类的结构,而不是测试精确等效性。

我找到了适合我的情况的解决方案,基本上是使用 a2 而不是 a。然后,当我通过与问题中相同的过程将 a2 转换为字符串并返回数组(比如 a3)时,我可以获得 numpy.all(a2==a3) 的 True。与 a 不同,a2 和 a3 的所有值似乎都在所需值内 +/- 1e-14 并且彼此相同。