Pandas read_excel读取大整数出错如何获取Excel原始精确值
偏差产生原因
- Excel存储常规数值采用IEEE 754双精度(64位)浮点数规范,这类浮点数可无偏差精确表示的整数上限为
2^53 = 9007199254740992,超过这个阈值的整数无法被双精度浮点数精确存储,相邻可精确表示的整数间隔会随数值增大逐步提升到2、4、8甚至更高,你遇到的差值为4的偏差,就是数值到对应区间后浮点数精度间隔导致的。 pandas.read_excel默认调用的解析引擎(旧版为xlrd,新版为openpyxl),默认读取逻辑会先将单元格数值转换为双精度浮点数,再根据推断转换为对应数据类型。只要经过浮点数中转这一步,精度损失就已经产生,后续哪怕强制转换为int64类型,丢失的精度也无法恢复。
读取精确原始值的方法
不要走浮点数中转逻辑,直接解析xlsx文件内存储的原始数字文本再转整数即可,推荐两种可落地的方案:
方案1:使用calamine引擎(最简便)
python-calamine是基于Rust开发的Excel解析库,作为pandas读取引擎时会直接解析xlsx压缩包内XML存储的原始数字文本,不会做浮点数中转,不会丢失大整数精度,且读取速度远快于openpyxl/xlrd。
- 先安装依赖:
pip install python-calamine - 读取文件时指定引擎和对应列的类型即可:
import pandas as pd xlsx = pd.read_excel( "file.xlsx", sheet_name="samples", engine="calamine", dtype={"timestamp [us]": "int64"} ) print(xlsx["timestamp [us]"][:1])
方案2:基于openpyxl手动读取(无需额外安装依赖)
如果不想新增依赖,可以用openpyxl的只读模式加载文件,该模式下openpyxl会直接返回单元格存储的原始整数值,不会主动转浮点数:
from openpyxl import load_workbook import pandas as pd # 只读模式加载工作簿,data_only=True读取单元格计算后的值 wb = load_workbook("file.xlsx", read_only=True, data_only=True) ws = wb["samples"] # 提取表头 row_iter = ws.iter_rows(values_only=True) headers = next(row_iter) # 逐行提取数据 data = list(row_iter) xlsx = pd.DataFrame(data, columns=headers) print(xlsx["timestamp [us]"][:1])
注意:不要尝试对已经经过浮点数转换的数值做修正,这类精度损失是不可逆的,必须从读取环节避开浮点数中转逻辑。
内容的提问来源于stack exchange,提问作者Vishnu Nadhan
相关产品推荐
相关产品推荐

