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

Python调用csv.DictWriter写入CSV时去除科学计数法避免精度丢失

Python写入CSV大浮点数自动转科学计数法、精度丢失解决方案

问题核心原因

  • 原生Python float是双精度类型,有效数字仅15-17位,示例代码中定义的几十位浮点数在赋值阶段就已经出现精度损失,不是CSV写入环节才导致的丢精度
  • 直接将列表作为单元格值传入csv.DictWriter.writerow()时,模块会自动对列表调用str()做类型转换,大浮点数转字符串默认使用科学计数法格式
  • 常规字符串格式化操作如果基于已经丢精度的float类型处理,无法还原原始数值,解决不了根本问题

可落地实现方案

方案核心逻辑:用Decimal类型存储大数值从根源避免精度丢失,自定义数值格式化逻辑禁用科学计数法,流式写入适配大规模数据场景。

import csv
from decimal import Decimal

csv_file = r"D:/temp/test.csv"

# 注意:大数值禁止直接定义为float类型,通过字符串传入Decimal构造,从源头保证精度
# 若原始数据来自接口、数据库等数据源,直接取数值字符串传入Decimal即可,不要做float中转
long_num_dict = {
  'number1': [
      Decimal("123456789984987954654687654.20"),
      Decimal("19879842619984987954654687654.20")
  ],
  'number2': [
      Decimal("515456789984987954654687654.20"),
      Decimal("19879842619989875465654687654.20")
  ]
}

def format_decimal_num(num: Decimal) -> str:
    """将Decimal格式化为无科学计数法的定点数字符串"""
    return format(num, 'f')

def process_cell_val(val):
    """处理单元格值,兼容单个数值、列表类型,自动格式化所有大数字"""
    if isinstance(val, list):
        processed_item_list = []
        for item in val:
            if isinstance(item, Decimal):
                processed_item_list.append(format_decimal_num(item))
            else:
                processed_item_list.append(str(item))
        # 自定义拼接,避免默认str(list)给数值加单引号
        return f"[{', '.join(processed_item_list)}]"
    elif isinstance(val, Decimal):
        return format_decimal_num(val)
    # 字符串、整数等常规类型直接返回原值
    return val

# 写入时指定newline=''避免CSV生成多余空行,指定utf-8编码兼容多环境打开
with open(csv_file, 'w', newline='', encoding='utf-8') as f:
    writer = csv.DictWriter(f, fieldnames=long_num_dict.keys())
    writer.writeheader()
    # 逐值处理后写入,大场景下可替换为逐行读取、逐行处理、逐行写入的流式逻辑
    processed_row = {col_name: process_cell_val(col_val) for col_name, col_val in long_num_dict.items()}
    writer.writerow(processed_row)

运行后生成的CSV内容如下,无科学计数法、无精度丢失:

number1,number2
"[123456789984987954654687654.20, 19879842619984987954654687654.20]","[515456789984987954654687654.20, 19879842619989875465654687654.20]"

大规模数据场景适配注意事项

  • 禁止一次性加载全量数据到内存,若待处理数据量较大,采用逐行读取源数据、逐行做格式化处理、逐行调用writer.writerow()的流式处理逻辑,内存占用不会随数据量上涨
  • Decimal格式化性能足够支撑百万级以上数值处理,无明显性能瓶颈,比pandas默认写入逻辑的精度稳定性更高
  • 若使用pandas处理,不要直接用默认to_csv写入大数值列,需提前将所有大数值列转换为格式化后的字符串类型,否则pandas会默认将数值转为float64类型,同样会出现科学计数法和精度丢失问题
  • 所有大数值处理环节禁止出现float类型中转,否则会直接引入不可逆的精度损失

内容的提问来源于stack exchange,提问作者Flabala

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 21:01:23