首页 > 解决方案 > 我必须压缩许多相似的文件,我可以利用它们相似的事实吗?

问题描述

我有一个包含许多不同样本(numpy 数组)的数据集。将所有内容仅存储在一个文件中是相当不切实际的,因此我存储了许多不同的“npz”文件(以 zip 压缩的 numpy 数组)。

现在我觉得如果我能以某种方式利用所有文件彼此相似的事实,我可以实现更高的压缩系数,这意味着我的磁盘上的占用空间要小得多。

是否可以单独存储“zip 基础”?我的意思是对所有文件一起计算并体现它们的统计特征并且是解压缩所需的东西,但在所有文件之间共享。

我会说“zip 基础”文件和一个单独的压缩文件列表,它的大小比单独压缩的每个文件要小得多,并且要解压缩,我每次都使用共享“zip 基础”来处理每个文件。

技术上可行吗?有没有像这样工作的东西?

标签: pythonzipcompression

解决方案


tldr; 这取决于每个单独文件的大小和其中的数据。例如,特征/用例/访问模式可能在 234567x100 字节文件和 100x234567 字节文件之间有很大差异。

现在我觉得如果我能以某种方式利用所有文件彼此相似的事实,我可以实现更高的压缩系数,这意味着我的磁盘上的占用空间要小得多。

可能。共享压缩优势将随着文件大小的增加而减少。

无论如何,即使使用 Mono File 实现(比方说标准zip)也可以为许多非常小的文件节省大量有效的磁盘空间,因为它避免了文件系统管理单个文件所需的开销;如果不出意外,许多实现必须与完整块对齐[例如。512-4k 字节]。另外,使用普遍支持的格式进行免费压缩。

是否可以单独存储“zip 基础”?我的意思是对所有文件一起计算并体现它们的统计特征并且是解压缩所需的东西,但在所有文件之间共享。

这种“zip 基础”有时被称为预共享字典。

我会说“zip 基础”文件和一个单独的压缩文件列表,它的大小比单独压缩的每个文件要小得多,并且要解压缩,我每次都使用共享“zip 基础”来处理每个文件。

技术上可行吗?有没有像这样工作的东西?

是的,这是可能的。SDCH (Shared Dictionary Compression for HTTP)就是为常见的 Web 文件(例如 HTTP/CSS/JavaScript)设计的一种此类实现。在某些情况下,它可以实现比标准 DEFLATE 更高的压缩率。

可以使用许多压缩算法来模拟该方法,这些算法适用于压缩字典被编码为写入流的一部分的流。(U = 未压缩,C = 压缩。)

压缩:

[U:shared_dict] + [U:data] -> [C:shared_dict] + [C:data]
^-- "zip basis"                                 ^-- write only this to file
                              ^-- artifact of priming

解压:

[C:shared_dict] + [C:data] -> [U:shared_dict] + [U:data]
^-- add this back before decompressing!         ^-- use this                                                          

节省的总空间取决于许多因素,包括初始启动字典的有用程度以及特定的压缩机详细信息。由于使用了充当查找字典的滑动窗口,LZ78 式的实现特别适合上述方法。

或者,也可以使用特定领域的知识和/或编码来通过专门的压缩方案实现更好的压缩。这方面的一个例子是 SQL Server 的页面压缩,它利用不同行上的列之间的数据相似性。


推荐阅读