【问题标题】:pandas pytables append: performance and increase in file sizepandas pytables 追加:性能和文件大小的增加
【发布时间】: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,)

【问题讨论】:

    标签: python performance pandas hdfs pytables


    【解决方案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 函数。我现在已经这样做了,一切似乎都很好。我会听从您关于压缩的建议,再次感谢您的帮助!
    猜你喜欢
    • 2021-09-25
    • 1970-01-01
    • 2013-12-02
    • 2015-03-11
    • 2012-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多