【问题标题】:Python different value when printing and reading [duplicate]打印和读取时Python不同的值[重复]
【发布时间】:2013-04-30 15:20:18
【问题描述】:

我在“.fits”表中有一个存储值(这应该没有问题)。 我读了表,然后做

In [2]: a['RA_touse'][0]
Out[2]: 161.65813

这是真正的存档值。但是,我会这样做:

In [3]: print a['RA_touse'][0]
161.658

我得到一个截断的值。我将 python 与 POSTGRES 一起使用,这种行为会带来一些精度问题。

谁能向我解释这种行为,以及如何解决它?我需要我的数据保持相同的格式,而不是更改它(即,repr() 函数会将所有内容都转换为字符串)。

非常感谢!

为清楚起见进行编辑:

我正在使用 python 脚本来创建数据库。我要做的是

con = psycopg2.connect('todatabase')
cur = con.cursor()
for i in vector_of_something:
    value1 = table['column1'][i]
    value2 = table['column2'][i]
    values = (values1,values2)
    values = [str(value) for value in values]
    command = 'INSERT INTO table values (%s,%s)'
    cur.execute(command,values)
con.commit()

问题是我在数据库中得到“161.658”,而不是 1.65813。

【问题讨论】:

  • 您在 Python 和 DB 中使用什么数据类型?尝试使用浮点值的十进制表示时会失去精度。此外,在格式化数字以进行打印时会发生截断,这实际上并不反映存储值的精度损失。
  • 我在这种情况下使用浮点数。我有类似的东西: value = a['RA_touse'][0] 然后将其转换为字符串,并将其上传到 postgresql
  • 编辑后。为什么不将 POSTGRES 中的值存储为数字类型,而不是字符串?
  • 用这个脚本填充数据库,然后反向使用它来获取值。一些值是字符串(如引用),但另一些是数字类型,必须保留,以便 python 从数据库中获取它们时可以正常使用它们。 (也许不是,我从数据库操作开始)

标签: python postgresql truncation


【解决方案1】:

您应该使用带有最大小数点数的字符串格式。

print '%.10f' % a['RA_touse'][0]

【讨论】:

  • 如果我这样做,我会得到一个奇怪的值,比如 161.6581268311。问题是值不同并且具有不同的精度(它们来自不同的来源),我只想保留记录的值,而不是表示。在某些情况下是 4 位小数,在其他情况下可能是 6。
  • 你试过print '%f' % a['RA_touse'][0]吗?
  • 您正在处理浮点数。它们在系统中以二进制表示,然后转换为/从十进制转换为 i/o。以 2 为底的浮点值不能代表与以 10 为底的浮点相同的精确值,因此当在基数之间转换值时,会执行一个近似过程。如果您想保留精确的十进制值,请使用 Decimal 之类的内容。
【解决方案2】:

当您使用浮点值时,您必须记住,您是在代码或应用程序接口中以 10 为基数编写它们(通常),但它们是以 2 为基数存储的。对于整数值也是如此,但这不是问题,因为所有整数都可以在任何基础上准确表示。这里有一些十进制>二进制转换的例子来说明问题。

dec   bin
.1    .000110011(0011 repeating)
.2    .0011(r)
.25   .01
.3(r) .01(r)
.5    .1

易于以 10 为基数表示的值并不总是可以以 2 为基数进行有限表示。The Decimal object 的存在专门用于满足保持浮点运算的十进制精度的需要。

【讨论】:

    【解决方案3】:

    我发现问题是字符串转换。最后,我将所有内容都转换为字符串以格式化 POSTGRESQL 的所有内容。如果我这样做了

    values = [repr(vaue) for value in values]
    

    上传的值是正确的。

    感谢您的帮助!

    【讨论】:

    • 鉴于您在@Shane 的回答中描述为“奇怪值”的 cmets 中的“奇怪值”,使用提取值运行计算时您仍然会遇到问题。所有字符串转换也会对性能造成影响。
    • 嗯...字符串转换完成得非常快(表格在 10 秒内填充完毕,有 >40000 行并包括一些计算)。另一方面,你对之后的计算是正确的......看起来我不会使用“十进制”模块!
    猜你喜欢
    • 2021-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-01
    • 1970-01-01
    • 2020-08-28
    • 1970-01-01
    相关资源
    最近更新 更多