pandas pytables 追加:性能和文件大小的增加
Posted
技术标签:
【中文标题】pandas pytables 追加:性能和文件大小的增加【英文标题】:pandas pytables append: performance and increase in file size 【发布时间】:2014-05-21 00:41:27 【问题描述】:我有 500 多个 PyTables
存储,每个存储包含大约 300Mb 的数据。我想将这些文件合并到一个大存储中,使用 pandas append
,如下面的代码所示。
def merge_hdfs(file_list, merged_store):
for file in file_list:
store = HDFStore(file, mode='r')
merged_store.append('data', store.data)
store.close()
追加操作非常慢(将单个存储追加到 merged_store
最多需要 10 分钟),奇怪的是 merged_store
的文件大小似乎每追加一个存储增加 1Gb。
我已经指出了根据文档应该可以提高性能的预期行总数,并且在阅读 Improve pandas (PyTables?) HDF5 table write performance 之后,我预计写入时间会很长,但是每 300Mb 几乎 10 分钟似乎太慢了,我不能了解为什么尺寸会增加。
我想知道我是否遗漏了什么?
有关其他信息,这里是 500 个 PyTables 之一的描述。
/data/table (Table(272734,)) ''
description :=
"index": Int64Col(shape=(), dflt=0, pos=0),
"values_block_0": Float64Col(shape=(6,), dflt=0.0, pos=1),
"id": StringCol(itemsize=11, shape=(), dflt='', pos=2),
"datetaken": Int64Col(shape=(), dflt=0, pos=3),
"owner": StringCol(itemsize=15, shape=(), dflt='', pos=4),
"machine_tags": StringCol(itemsize=100, shape=(), dflt='', pos=5),
"title": StringCol(itemsize=200, shape=(), dflt='', pos=6),
"country": StringCol(itemsize=3, shape=(), dflt='', pos=7),
"place_id": StringCol(itemsize=18, shape=(), dflt='', pos=8),
"url_s": StringCol(itemsize=80, shape=(), dflt='', pos=9),
"url_o": StringCol(itemsize=80, shape=(), dflt='', pos=10),
"ownername": StringCol(itemsize=50, shape=(), dflt='', pos=11),
"tags": StringCol(itemsize=505, shape=(), dflt='', pos=12)
byteorder := 'little'
chunkshape := (232,)
【问题讨论】:
【参考方案1】:这基本上是我最近回答的here的答案。
底线是这个,你需要关闭索引store.append('df',df,index=False)
。在创建 store 的时候,在最后建立索引。
此外,在合并表时也要关闭压缩。
索引是一项相当昂贵的操作,如果我没记错的话,它只使用一个处理器。
最后,请确保您使用 mode='w'
创建合并,因为所有后续操作都是附加操作,并且您希望从一个干净的新文件开始。
我也不会预先指定chunksize
。相反,在您创建最终索引后,使用ptrepack
执行压缩并指定chunksize=auto
,它将为您计算它。我认为这不会影响写入性能,但会优化查询性能。
您也可以尝试将 chunksize
参数调整为更大的数字 append
(这是写入块大小)。
显然要确保每个附加表具有完全相同的结构(如果不是这种情况会引发)。
我创建此问题是为了增强“内部”执行此操作:https://github.com/pydata/pandas/issues/6837
【讨论】:
谢谢,删除索引大大加快了进程。但是,我仍然得到非常大的文件大小:对于我附加到合并存储的每个 300Mb 表,我会增加 1Gb 的大小,最终将填满我的磁盘。这不应该是由于压缩,因为我没有对 300Mb 文件应用压缩。 表格完全一样吗?当你连接它们时,字符串都将是生成的表字符串大小(根据最小值可能更大) 我已经对数据进行了解析,因此每个表中长字符串的大小都被限制为固定值(以避免append
操作中的错误)。这些表并不完全相同,它们的大小也略有不同,但我为合并表保留了相同的 min_itemsize
参数,所以我不希望字符串改变大小...
您确定为每个字段都指定了min_itemsize
吗? (例如,对单个文件和合并文件进行ptdump -av
比较。这可能会产生巨大的差异。假设在单个文件中未使用min_itemsize
指定字段,但在合并文件中,您可以轻松地将大小翻倍(例如,它在单个文件中为 10,但在合并文件中为 100)。压缩应该对此有很大帮助。所以也要比较压缩文件。看到你的数据集非常大,我肯定会使用 @987654335 压缩它@ 因为它也会使查询更快。
因为所有表都是使用相同的min_itemsize
参数生成的(并且包含固定最大长度的字符串),我假设合并表的字段将自动以正确的大小创建而无需明确将 min_itemsize
参数传递给 append 函数。我现在已经这样做了,一切似乎都很好。我会听从您关于压缩的建议,再次感谢您的帮助!以上是关于pandas pytables 追加:性能和文件大小的增加的主要内容,如果未能解决你的问题,请参考以下文章
使用另一个 pandas DataFrame 更新存储在 Pytable 中的 pandas DataFrame
使用 pandas/pytables 处理与多个索引值关联的关联数据项列表的正确方法
如何将 Pandas DataFrame 存储为 HDF5 PyTables 表(或 CArray、EArray 等)?