HDF5中用于Python/pandas快速读写的推荐压缩格式是什么?

13

我已经多次阅读到,在HDF5中启用压缩可以提高读写性能。

我想知道在以下情况下,什么样的理想设置可以实现良好的读写性能:

 data_df.to_hdf(..., format='fixed', complib=..., complevel=..., chunksize=...)

我已经在使用fixed格式(即h5py),因为它比table更快。我的处理器性能很强,对磁盘空间不太关心。

我经常将DataFramefloat64str类型存储在大约2500行x9000列的文件中。


1
压缩级别基本上是处理速度和磁盘使用之间的权衡。如果您拥有快速处理器并且不关心磁盘空间,那么它实际上并不重要,只需让它使用默认值即可。当然,这是其中一种因人而异的情况,在您特定的数据上尝试几个不同的压缩级别并看看哪个最适合是无可替代的。此外,请检查每个级别的读取与写入性能,因为它们可能不对称。 - JohnE
默认情况下没有压缩,我相信我可以改进它;-) 我得自己试试,但会感激好的直觉...一些压缩算法适用于速度,另一些适用于压缩级别。而且不确定 chunksize 实际上影响什么或者压缩是否实际上作用于 str,因为我认为它存储为 Object。我还需要在几台不同的机器上运行这个程序。 - Mark Horvath
我的目的是提高执行时间。我相信通过应用压缩(例如,AHL使用lz4来加速存储数据),我也可以进一步改善它。 - Mark Horvath
2
我认为就执行时间而言,试用不同类型和级别的压缩是没有太多替代方法的,尽管也许其他人会有一些一般性的指针。就字符串而言,您可能还想将它们存储为类别值。这大致相当于字符串压缩,但也将在数据框加载到内存中时使您受益,而不仅仅是在其存储时。 - JohnE
已找到两个类似的线程 (hdf5 并发pytables 写入性能)。在这些例子中,使用 blosc 压缩似乎可以达到或超越无压缩的性能。 - Mark Horvath
1个回答

18

有几个可能的压缩筛选器可以使用。自从HDF5版本1.8.11以来,您可以轻松地注册第三方压缩筛选器。

关于性能:

这可能取决于您的访问模式,因为您可能需要为您的块定义适当的维度,以便它与您的访问模式对齐,否则性能将受到很大影响。例如,如果您知道通常会访问一列和所有行,则应相应地定义块形状(1, 9000)。请参见此处此处此处获取一些信息。

然而,据我所知,pandas通常会将整个HDF5文件加载到内存中,除非您使用read_tableiterator(请参见此处)或自己进行部分IO(请参见此处),因此并不能从定义好的块大小中获得太多好处。

尽管如此,您仍然可能从压缩中受益,因为将压缩数据加载到内存中并使用CPU解压缩它可能比加载未压缩的数据更快。

关于您最初的问题:

我建议查看Blosc。它是一个支持各种不同压缩筛选器的多线程元压缩库:

  • BloscLZ:内部默认压缩器,基于FastLZ。
  • LZ4:一种紧凑、非常流行和快速的压缩器。
  • LZ4HC:LZ4的改进版本,以牺牲速度为代价产生更好的压缩比。
  • Snappy:一种广泛使用的流行压缩器。
  • Zlib:经典压缩器;比前面的压缩器略慢,但能够实现更好的压缩比。

这些压缩器各有所长,最好的方法是尝试使用您的数据进行基准测试,看哪个效果最好。


太好了!“chunksize”的经验法则很有道理,事实上,由于我使用的是“fixed”格式(我在文件系统级别上进行分块),所以我总是读取整个数据。现在我明白为什么所有我找到的示例都使用“blosc”了,谢谢! - Mark Horvath
我认为pandas将整个文件读入内存的原因与是否使用“fixed”无关。它是这样设计的。要在pandas中进行统计(summean),pandas需要读取整个数据集。您可以降级到PyTables,它支持查询,不会将整个数据集读入内存,而只是逐块读取(但您将没有方便的panda函数)。或者对于不适合内存的数据集,Blaze可能是一个很好的解决方案。 - Ümit
chunks=(1, 9000) 不会表示你访问一行和所有列吗?因为HDF5按行主顺序组织。 - collector

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接