【问题标题】:Rounding error from array -> string -> array conversion来自数组的舍入错误 -> 字符串 -> 数组转换
【发布时间】:2015-12-21 18:48:40
【问题描述】:

我正在尝试通过水平连接 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

从数组到字符串再转换回来时是否存在一些浮点/舍入错误(a2 实际上比 a 更接近 196.275 的期望值)?如何使值相等?我的怀疑是,当我通过迭代添加最初生成 col1 来产生错误时,这会加剧后面数组索引中的错误。这是否意味着我应该改为显式枚举 col1 的值,或者是否有解决方法?

【问题讨论】:

  • 如果您需要 numpy 数组往返,请使用 numpy.save。不要自己手动将它们转换为字符串。
  • 我必须将它们转换为字符串,以便与我正在使用的实验室设备进行通信,因为 API 只能识别字符串。我希望能够写入设备,然后从设备读回并比较两者以确保它正确接收数据。
  • 但是在那种情况下,为什么需要将设备的响应转换回数字呢?如果你只是想检查输入和输出是否相等,你不应该将它们作为字符串进行比较吗?
  • 问题是,在比较之前我得把数据清理一下。我知道我至少需要将第一列四舍五入到最接近的小数点后第三位(还不确定其他列)。
  • 啊,所以设备基本上在输出上加了一点“噪音”。在这种情况下,您想要做的就是有容差进行相等性检查。在 numpy 中,这是 numpy.allclose,您的 rtolatol 参数选择得当。我不知道为什么 numpy.all 为您工作(根据您的回答),但我不会指望它。

标签: python arrays string numpy rounding-error


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2015-02-26
      • 2012-07-15
      • 1970-01-01
      • 2017-12-02
      • 1970-01-01
      • 2016-08-29
      • 2021-11-22
      • 1970-01-01
      • 2013-06-23
      相关资源
      最近更新 更多