Pandas保存含字符串列的DataFrame为HDF5时文件体积异常偏大
问题根源
这部分多出的约1MB空间是PyTables(pandas操作HDF5的底层依赖)对字符串列的默认存储预留空间,和实际存储的字符串内容长度无关:
- 存储数值类型列时,数值本身是固定字节长度(比如int64类型单值占8字节),底层会按实际数据量精准分配空间,再加上HDF5文件头、pandas元数据、索引信息,最终生成的7KB左右文件属于正常体积。
- 存储字符串类型列时,使用默认的
fixed存储格式时,PyTables会预分配大小为1MB(1048576字节)的字符串存储块,作为后续写入更多字符串数据的预留池,不管你实际写入的是3字节的'bar'还是更短的字符串,这部分预留块都会被完整写入文件。你测得的1063224字节总大小,刚好是1MB预留块加上元数据、索引的体积,和差值完全吻合。
这部分预留空间不会随着你存储的单条字符串长度变化而变化,也不会因为你只存1条短字符串就缩小。
优化方案
可以根据你的使用场景选以下方案消除冗余空间:
- 如果你存储的字符串长度固定,直接将列转为定长字节类型,底层会按你指定的长度分配空间,不会预留1MB块:
from pathlib import Path import pandas as pd data_frame = pd.DataFrame({'foo': ['bar']}) # 指定字符串为3字节定长类型 data_frame['foo'] = data_frame['foo'].astype('S3') data_frame.to_hdf(Path.home() / 'Desktop' / 'file.hdf5', key='baz', mode='w')
修改后生成的文件体积和存储数值时基本一致,在7KB左右。
- 如果你需要存储长度不固定的字符串,可以改用
table格式存储,同时开启压缩,预留块会被压缩到极小体积:
from pathlib import Path import pandas as pd data_frame = pd.DataFrame({'foo': ['bar']}) data_frame.to_hdf( Path.home() / 'Desktop' / 'file.hdf5', key='baz', mode='w', format='table', complevel=9, complib='blosc' )
补充说明:如果你后续要在同一个HDF5文件里存储十万条以上的字符串数据,这1MB预留空间的占比会降到可以忽略的程度,且预留块不会重复分配,不需要特意调整存储参数。
内容的提问来源于stack exchange,提问作者reyymo
相关产品推荐
相关产品推荐

