You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Pandas读取CSV时浮点数出现多余尾数位的问题求助

问题描述

使用pd.read_csv读取CSV文件时,指定dtype={'col1': str, 'column_with_trash': float},但DataFrame中column_with_trash列出现原文件没有的多余小数位。未执行运算时导出的1.xlsx中,该列值与1524684.3740493相减得到0.0000000779982656240463;执行减法运算后导出的2.xlsx结果一致。尝试设置float_precision为"high"、"round_trip"及None,也用了df['column_with_trash'].round(9),都没解决9位小数处的精度问题,影响计算结果。

代码示例:

df = pd.read_csv(f'{name}.csv', sep=',', decimal='.', dtype={'col1': str, 'column_with_trash': float})

df[df['col1'] == '0001'].to_excel('1.xlsx')
df['column_with_trash'] = df['column_with_trash'] - 1524684.3740493
df[df['col1'] == '0001'].to_excel('2.xlsx')

原CSV内容:

col1,col2,col3,col4,col5,col6,column_with_trash
0001,TP,2021-12-31,T,N,2130875.40078,1524684.374049378
解决方案
  • 用Decimal类型替代float读取:Python的decimal.Decimal可精确表示十进制小数,彻底避免浮点数精度丢失。读取时先以字符串读取目标列,再转换为Decimal类型:

    from decimal import Decimal
    
    df = pd.read_csv(f'{name}.csv', sep=',', dtype={'col1': str, 'column_with_trash': str})
    df['column_with_trash'] = df['column_with_trash'].apply(Decimal)
    

    后续运算直接使用Decimal计算,精度完全匹配CSV中的原始值。

  • 使用更高精度的浮点类型:若坚持使用浮点类型,可尝试将列指定为numpy.float128(支持更高精度,注意部分平台可能不兼容):

    import numpy as np
    
    df = pd.read_csv(f'{name}.csv', sep=',', decimal='.', dtype={'col1': str, 'column_with_trash': np.float128})
    
  • 导出Excel时强制设置数值格式:即使DataFrame内部存在微小精度误差,可在导出时为目标列指定固定小数位数,避免显示多余误差:

    from openpyxl.styles import numbers
    
    with pd.ExcelWriter('1.xlsx') as writer:
        target_df = df[df['col1'] == '0001']
        target_df.to_excel(writer, index=False)
        worksheet = writer.sheets['Sheet1']
        # 假设column_with_trash是第7列(G列),设置为9位小数格式
        worksheet.column_dimensions['G'].number_format = '0.000000000'
    
  • 字符串拆分运算(极端场景):如果仅需针对特定值做减法,可提取字符串中的数值部分,拆分整数和小数段后计算,再拼接结果,完全规避浮点数问题。

内容的提问来源于stack exchange,提问作者Tomasz Jeliński

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 10:45:45