为什么用 Pandas 写入时 CSV 文件比 HDF5 文件小?

Why are CSV files smaller than HDF5 files when writing with Pandas?

import numpy as np
import pandas as pd

df = pd.DataFrame(data=np.zeros((1000000,1)))
df.to_csv('test.csv')
df.to_hdf('test.h5', 'df')

ls -sh test*
11M test.csv  16M test.h5

如果我使用更大的数据集,那么效果会更大。使用如下所示的 HDFStore 不会改变任何内容。

store = pd.HDFStore('test.h5', table=True)
store['df'] = np.zeros((1000000,1))
store.close()

编辑: 没关系。这个例子很糟糕!使用一些非平凡的数字而不是零改变了故事。

from numpy.random import rand
import pandas as pd

df = pd.DataFrame(data=rand(10000000,1))
df.to_csv('test.csv')
df.to_hdf('test.h5', 'df')

ls -sh test*
260M test.csv  153M test.h5

将数字表示为浮点数应该比将它们表示为每个数字一个字符的字符串占用更少的字节。这通常是正确的,除了在我的第一个示例中,其中所有数字都是“0.0”。因此,不需要很多字符来表示数字,因此字符串表示形式小于浮点表示形式。

简要说明:

  • csv 文件是 'dumb':它一次是一个字符,所以如果您打印(比如说,四字节)浮点数 1.0 到十位数字,您实际上使用了那么多字节-- 但好消息是 csv 压缩得很好,所以考虑 .csv.gz.

  • hdf5 是一种 元格式 并且 没有免费的午餐 定理仍然成立:条目和值需要存储在某处。这可能会使 hdf5 变大。

但是您忽略了一个更大的问题:csv 只是文本。它的精度有限——而 hdf5 是几种 binary(序列化)格式之一,它以更高的精度存储数据。在这方面也确实是同理。

对于 .csv,您的方法存储这样的字符:

999999,0.0<CR>

每个值最多 11 个字符。在 100 万个值时,这接近 11MB。

HD5 似乎将每个值存储为 16 字节浮点数,不要介意它一遍又一遍地是相同的值。所以这是 16 字节 * 1,000,000,大约是 16 MB。

存储的不是 0.0,而是一些随机数据,.csv 很快就变成 25MB 甚至更多,而 HDF5 文件的大小保持不变。虽然 csv 文件失去了准确性,但 HDF5 保留了它。