Python HDF如何在不重新打包的情况下处理已删除数据集释放的空间
我特别提到HDF与使用Pytables/Pandas接口,但我认为这适用于HDF 我知道一旦数据集被删除,HDF就不会回收空间,您必须使用h5repack/ptrepack来回收空间。我使用这种方法的问题是,我发现这些工具非常慢,特别是对于千兆字节(我的文件约为20GB)的文件。因此,如果您必须添加/删除具有某种规律性的派生数据集(例如,在调试生成该数据的东西时),这是不实际的Python HDF如何在不重新打包的情况下处理已删除数据集释放的空间,python,pandas,hdf5,pytables,Python,Pandas,Hdf5,Pytables,我特别提到HDF与使用Pytables/Pandas接口,但我认为这适用于HDF 我知道一旦数据集被删除,HDF就不会回收空间,您必须使用h5repack/ptrepack来回收空间。我使用这种方法的问题是,我发现这些工具非常慢,特别是对于千兆字节(我的文件约为20GB)的文件。因此,如果您必须添加/删除具有某种规律性的派生数据集(例如,在调试生成该数据的东西时),这是不实际的 所以-我的问题是,如果不重新打包文件,删除数据集的空间会发生什么情况?在你重新打包文件之前它就丢失了吗?下次尝试向文件
所以-我的问题是,如果不重新打包文件,删除数据集的空间会发生什么情况?在你重新打包文件之前它就丢失了吗?下次尝试向文件a-la SQL写入内容时,是否将其标记为可用于存储?换句话说,释放的空间有用吗,还是只需要每隔一段时间重新打包文件?我不知道PyTables背后的代码,因此无法给出PyTables开发的正式答案。在PyTables Google Groups网站上提问,Francesc Alted可能会回答。 在此期间,我编写了一个小测试来练习这种行为。下面的例子已经修改,以符合我11月8日的评论。它现在创建3个HDF5文件:
我的结论是:当新表与已删除表的大小相同时,PyTables足够聪明,可以回收已分配(但未使用)的空间。我怀疑如果新表更大,您可能会得到不同的结果 下面是一个简单的例子: 在我的测试中,文件1、2和3都是114MB
import tables as tb
import numpy as np
data1 = np.arange(1000000.)
data2 = 2.0*data1
data3 = 3.0*data1
ds_dt = np.dtype({'names':['data1', 'data2', 'data3'],
'formats':[(float), (float), (float)] })
rec_arr = np.rec.fromarrays([data1, data2, data3], dtype=ds_dt)
with tb.File('SO_58736920_1.h5','w') as h5f:
tb1 = h5f.create_table('/','test1',obj=rec_arr)
tb2 = h5f.create_table('/','test2',obj=rec_arr)
tb3 = h5f.create_table('/','test3',obj=rec_arr)
tb4 = h5f.create_table('/','test4',obj=rec_arr)
tb5 = h5f.create_table('/','test5',obj=rec_arr)
with tb.File('SO_58736920_2.h5','w') as h5f:
tb1 = h5f.create_table('/','test1',obj=rec_arr)
tb2 = h5f.create_table('/','test2',obj=rec_arr)
tb3 = h5f.create_table('/','test3',obj=rec_arr)
tb4 = h5f.create_table('/','test4',obj=rec_arr)
tb5 = h5f.create_table('/','test5',obj=rec_arr)
tb1._f_remove()
tb2._f_remove()
tb3._f_remove()
tb4._f_remove()
tb5._f_remove()
tb11 = h5f.create_table('/','test11',obj=rec_arr)
tb12 = h5f.create_table('/','test12',obj=rec_arr)
tb13 = h5f.create_table('/','test13',obj=rec_arr)
tb14 = h5f.create_table('/','test14',obj=rec_arr)
tb15 = h5f.create_table('/','test15',obj=rec_arr)
with tb.File('SO_58736920_3.h5','w') as h5f:
tb1 = h5f.create_table('/','test1',obj=rec_arr)
tb2 = h5f.create_table('/','test2',obj=rec_arr)
tb3 = h5f.create_table('/','test3',obj=rec_arr)
tb4 = h5f.create_table('/','test4',obj=rec_arr)
tb5 = h5f.create_table('/','test5',obj=rec_arr)
with tb.File('SO_58736920_3.h5','r+') as h5f:
h5f.root.test1._f_remove()
h5f.root.test2._f_remove()
h5f.root.test3._f_remove()
h5f.root.test4._f_remove()
h5f.root.test5._f_remove()
with tb.File('SO_58736920_3.h5','r+') as h5f:
tb11 = h5f.create_table('/','test11',obj=rec_arr)
tb12 = h5f.create_table('/','test12',obj=rec_arr)
tb13 = h5f.create_table('/','test13',obj=rec_arr)
tb14 = h5f.create_table('/','test14',obj=rec_arr)
tb15 = h5f.create_table('/','test15',obj=rec_arr)
我对您的示例进行了扩展,使用Pandas及其HDFStore和to_hdf函数进行了类似的操作,以测试关闭和重新打开文件时会发生什么。有趣的是,至少在熊猫的实现中,它似乎与关键联系在一起。删除某个键上的数据并将其替换似乎会使存档适应新的大小,但删除第一个键并将相同的数据添加到另一个键上会导致存档扩展。阅读您的文章后,我想知道我的示例是否太简单?也许一次性创建、删除和(重新)创建表可以避免“现实世界”中的某些事情(在现实世界中,您可以创建表并关闭,然后重新打开并删除一些表并关闭,然后重新打开并添加更多数据)。因此,我修改了我的示例,将3
与。。。as:
语句打开/关闭第二个HDF5文件3次。结果我得到了相同的结果:这两个文件大小相同。显然,熊猫实现PyTables的方式不同。