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 格式) 作为引擎尝试过这个。虽然前者产生了与 相同的错误结果xlsxwriter,Xlwt但实际上按预期工作并根据确切的变量值写入浮点数。.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)
我还尝试使用 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 读回文件时所看到的。
| 归档时间: |
|
| 查看次数: |
1381 次 |
| 最近记录: |