写入 Excel (.xlsx) 时 Numpy.float64 发生变化

ora*_*nge 5 python numpy xlwt pandas xlsxwriter

我注意到当某些 Numpy float64 值保存为 Excel 文件(通过 Pandas DataFrame)时,它们会发生变化。首先我认为这与 Excel 中的一些不精确有关,但 Excel 似乎将浮点数编码为双精度,所以我对这个观察有点困惑。

>>> import numpy as np
>>> import pandas as pd

# Create a floating point number that exhibits the problem.
>>> ba = bytearray(['\x53', '\x2a', '\xb0', '\x49', '\xf3', '\x79', '\x90', '\x40'])
>>> ba
bytearray(b'S*\xb0I\xf3y\x90@')
>>> f = np.frombuffer(ba)
>>> f[0]
1054.4875857854684

# Write to dataframe to save as Excel file.
>>> df = pd.DataFrame({'a': f})
>>> df.to_excel('test.xlsx', engine='xlsxwriter')

# Read excel file (when viewing the file in LibreOffice, the 
# value isn't 1054.4875857854684 any more).
>>> df2 = pd.read_excel('test.xlsx')
>>> df2.ix[0,'a']
1054.4875857854699
>>> df2.ix[0,'a'] == f[0]
False
Run Code Online (Sandbox Code Playgroud)

为什么不能从以前编写的 Excel 中读取相同的 float64?

我也用Openpyxl(.xlsx 格式) 和Xlwt(.xls 格式) 作为引擎尝试过这个。虽然前者产生了与 相同的错误结果xlsxwriterXlwt但实际上按预期工作并根据确切的变量值写入浮点数。.xlsx格式编写器引擎中是否有我想念的参数?

# this uses the xlwt engine
>>> df.to_excel('test.xls')
>>> df2 = pd.read_excel('test.xls')
>>> df2.ix[0,'a'] == f[0]
True
Run Code Online (Sandbox Code Playgroud)

jmc*_*ara 1

我还尝试使用 Openpyxl(.xlsx 格式)和 Xlwt(.xls 格式)作为引擎。虽然前者产生了与 xlsxwriter 相同的错误结果,但 Xlwt 实际上按预期工作并根据确切的变量值写入浮点数。

不同之处在于 .xls 是一种二进制文件格式,并且 IEEE 754 双精度的 64 位表示形式精确写入该文件,并且可以读回相同的 64 位。

然而,.xlsx 文件格式是 zip 容器中的文本 XML 文件的集合。因此,此类双精度数被写入双精度数的字符串表示形式(使用类似 的格式'%.16g'),并通过将该字符串表示形式转换回双精度数来读取。对于双精度数来说,这本质上是一个有损过程,因为绝大多数 IEEE 754 数字都没有精确的字符串表示形式。

例如,如果您在示例中采用 numpy 数字并以不同的精度对其进行格式化,您将得到不同的表示形式:

>>> '%.16g' % f[0]
'1054.487585785468'

>>> '%.17g' % f[0]
'1054.4875857854684'

>>> '%.18g' % f[0]
'1054.48758578546835'
Run Code Online (Sandbox Code Playgroud)

您还可以通过粘贴1054.4875857854684到 Excel 中的单元格、保存文件并检查输出来亲自演示这一点:

所以对于这样的文件:

在此输入图像描述

你会得到这样的东西:

$ unzip numpy.xlsx -d numpy

$ xmllint --format numpy/xl/worksheets/sheet1.xml | grep 1054
        <v>1054.4875857854599</v>
Run Code Online (Sandbox Code Playgroud)

这或多或少是您在使用 Pandas 读回文件时所看到的。