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

Python计算CSV发电量总和出现精度误差及优化方案咨询

误差来源

这个误差是二进制浮点数运算的固有精度问题:绝大多数十进制有限小数(比如0.1、0.2等)无法用64位双精度浮点数(也就是Python里的float类型)精确表示,存储时会做近似截断,多次累加后截断误差会逐步累积,最终就会出现这种和理论值差了极小尾数的情况,属于浮点数运算的正常现象,和你的计算逻辑、CSV读取逻辑无关。

更优实现方案

有几个可以优化的点:

  • 去掉多余的格式转换步骤:Python内置的csv模块本身支持自定义分隔符,不需要提前用tr命令把分号转成逗号,直接读取原CSV文件即可,减少不必要的IO操作和文件冗余。
  • 解决浮点精度误差:如果对数值精度要求高,可以用Python标准库的decimal模块做精确的十进制运算,从根源上避免浮点累加误差;如果只需要正常显示结果,也可以在输出时按需求保留小数位数即可。
  • 可选实现第一种计算逻辑:如果CSV的首尾行第二个字段的差值就是发电总量,这种方案的计算效率远高于逐行累加,尤其是大文件场景下优势更明显。

优化后的累加方案代码(无需提前转格式、无精度误差)

import csv
from decimal import Decimal

total = Decimal(0)
# 直接读取原分号分隔的CSV文件
with open('/home/LoadLive/day.csv', 'r', encoding='utf-8') as f:
    reader = csv.reader(f, delimiter=';')
    for row in reader:
        total += Decimal(row[2])
# 按需求输出,转float也不会有多余误差
print(f'The total is {float(total)}')
# 若需要输出精确十进制值:print(f'The total is {total}')

第一种计算逻辑的实现代码(效率更高)

import csv
from decimal import Decimal

with open('/home/LoadLive/day.csv', 'r', encoding='utf-8') as f:
    reader = csv.reader(f, delimiter=';')
    # 读取首行第二个字段值
    first_val = Decimal(next(reader)[1])
    # 遍历到最后一行
    last_row = None
    for row in reader:
        last_row = row
    last_val = Decimal(last_row[1])
    total = last_val - first_val
    print(f'The total is {float(total)}')

如果不需要高精度运算,只是不想显示多余的尾数,也可以直接格式化输出即可:

# 仅修改原来代码的输出行即可
print('The total is {:.2f}'.format(total))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 07:51:03