【问题标题】:python float64 type conversion issue with pandaspython float64类型转换问题与熊猫
【发布时间】:2021-09-14 08:14:37
【问题描述】:

我需要将 18 位 float64 pandas 列转换为整数或字符串以便可读,避免使用指数表示法。 但我目前还没有成功。

df=pd.DataFrame(data={'col1':[915235514180670190,915235514180670208]},dtype='float64')
print(df)
       col1
0  9.152355e+17
1  9.152355e+17

然后我尝试将其转换为 int64。但是最后 3 位数字出错了。

df.col1.astype('int64')
0    915235514180670208
1    915235514180670208
Name: col1, dtype: int64

但是你看..值是错误的。不知道为什么。 我从文档中读到 int64 应该能够容纳 18 位数字。

 int64  Integer (-9223372036854775808 to 9223372036854775807)

知道我做错了什么吗? 我怎样才能达到我的要求?

根据 Eric Postpischil 的评论提供更多信息。 如果 float64 不能容纳 18 位数字,我可能会遇到麻烦。 事情是我通过来自 DB 的 pandas read_sql 函数调用获取这些数据。它会自动将类型转换为 float64。 我没有看到在 pandas read_sql() 中提及数据类型的选项

任何人对我可以做些什么来克服这个问题有什么想法吗?

【问题讨论】:

  • A Float64 不能表示 915235514180670190。当该十进制数字转换为 Float64 时,结果是最接近的可表示值,915235514180670208。将 Float64 转换为十进制无法重现原始值,因为它不见了。
  • 问题是,我通过数据库中的 read_sql 将这些数据获取到 float64。那么,想想我能做什么?
  • 您可能想首先弄清楚数据库本身是否包含您需要的信息,或者在将值输入数据库时​​该信息是否丢失。 DB表的相关列的列类型是什么?如果数据库已经对该列使用 IEEE 754 浮点,那么这是一项不可能完成的任务。如果它使用其他精度更高的浮点类型或整数类型,那么您可能会做一些事情。

标签: python pandas floating-point


【解决方案1】:

问题在于 float64 是一个 53 位的尾数,可以表示 15 位或 16 位十进制数字 (ref)。

这意味着 18 位 float64 pandas 列是一种错觉。无需进入 Pandas,甚至无需进入 numpy 类型:

>>> n = 915235514180670190
>>> d = float(n)
>>> print(n, d, int(d))
915235514180670190 9.152355141806702e+17 915235514180670208

【讨论】:

    【解决方案2】:

    我解决了这个问题。考虑分享它,因为它可能对其他人有所帮助。

        #Preapring SQL to extract all rows.
        sql='SELECT * , CAST(col1 AS CHAR(18)) as DUMMY_COL FROM table1;'
        
        #Get data from postgres
        df=pd.read_sql(sql, self.conn)
        
        # converting dummy col to integer
        df['DUMMY_COL']=df['DUMMY_COL'].astype('int64')
        
        # removing the original col1 column with replacing the int64 converted one.
        df['col1'] = df['DUMMY_COL']
        df.drop('DUMMY_COL', axis=1, inplace=True)
    

    【讨论】:

      【解决方案3】:

      Pandas 中的read_sql 有一个coerce_float 参数可能会有所帮助。它默认开启,并记录为:

      尝试将非字符串、非数字对象(如 decimal.Decimal)的值转换为浮点数,这对 SQL 结果集很有用。

      将此设置为 False 有帮助,例如具有以下架构/数据:

      import psycopg2
      
      con = psycopg2.connect()
      
      with con, con.cursor() as cur:
          cur.execute("CREATE TABLE foo ( id SERIAL PRIMARY KEY, num DECIMAL(30,0) )")
          cur.execute("INSERT INTO foo (num) VALUES (123456789012345678901234567890)")
      

      我可以跑:

      print(pd.read_sql("SELECT * FROM foo", con))
      
      print(pd.read_sql("SELECT * FROM foo", con, coerce_float=False))
      

      这给了我以下输出:

         id           num
      0   1  1.234568e+29
      
         id                             num
      0   1  123456789012345678901234567890
      

      保持我插入的值的精度。

      您没有提供有关您正在使用的数据库的很多详细信息,但希望以上内容对某人有所帮助!

      【讨论】:

        猜你喜欢
        • 2012-10-04
        • 2017-08-24
        • 1970-01-01
        • 1970-01-01
        • 2018-12-07
        • 2019-11-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多