pandas pytables 追加:性能和文件大小增加
我有超过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()
但是,使用append
这个操作非常慢(把一个文件添加到merged_store
里要花上10分钟),而且奇怪的是,merged_store
的文件大小似乎每添加一个文件就增加1Gb。
我已经指明了预期的总行数,根据文档说这样应该能提高性能。我还看过提高pandas (PyTables?) HDF5表写入性能的内容,原本以为写入时间会很长,但每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 个回答
这基本上就是我最近回答的一个问题的答案,详细内容可以在这里找到。
简单来说,你需要在创建存储的时候关闭索引功能,使用 store.append('df',df,index=False)
。然后在最后再进行索引。
而且在合并表格的时候,也要关闭压缩功能。
索引操作是比较耗费资源的,而且如果我没记错的话,它只会使用一个处理器。
最后,确保在创建合并文件的时候使用 mode='w'
,因为后面的操作都是追加内容,你想要从一个干净的新文件开始。
我也不建议你提前指定 chunksize
。相反,在你创建完最终索引后,使用 ptrepack
来进行压缩,并指定 chunksize=auto
,这样系统会自动计算这个值。我认为这不会影响写入性能,但会优化查询性能。
你也可以尝试把 append
的 chunksize
参数调大一些(这是写入的块大小)。
当然,要确保每个追加的表格结构完全相同(如果不相同会报错)。
我为这个问题创建了一个改进建议,想要在内部实现这个功能:https://github.com/pydata/pandas/issues/6837