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 等)?

Numpy 和 PyTables 的浮点异常

提高 Pandas DataFrames 的行追加性能

pytables 的 DLL 加载失败