预压缩背后有科学依据吗?

Is there a science behind precompression?

这是我的问题 - 我有一个程序需要写入一些输出,而压缩后的输出需要尽可能小。

在这种情况下,人们可能会问的第一个问题是 "what datastructure should i use for my data?"。 XML? JSON?数据库? TXT?结构?

我认为说类似 C 的结构将在 压缩之前为您提供比任何其他格式都尽可能小的文件,这是没有争议的,但是我是努力弄清楚 "the rules" 将结构设计得尽可能小 压缩之后。所谓'precompression'.

的工作

例如,我最近不得不尽可能紧凑地存储一些 DNA。 DNA有5个字母,'A'、'C'、'G'、'T'、'N'。 N代表'dont know'。这意味着每个字符使用的最小二进制数是 3 位。

000 = A
001 = C
010 = G
011 = T
100 = N

所以我做了我认为正确的事情,写了一些代码,它接受一个固定长度的 DNA 字符串,比如说像 'AACA' 这样的四个字母,并将它转换成二进制,比如 '000 000 001 000 ' 然后 returns 两个字节 'xxxx0000','00001000' 其中 x 是填充(也是 0)。

实际程序用了76个DNA字母和returns29个字节,但思路是一样的。然后我将这 29 个字节写入一个结构(29 个 uint8 字节),其中包含 7211405 个 DNA 片段,这导致了一个 209130745 字节或 209Mb 的文件。 LZMA 压缩后,这个文件 sh运行k 下降到 74.3Mb.

然后我决定重新运行相同的encoding/compression,但这次将 DNA 的每个字母编码为 4 位。基本上,前一个文件的第 4 位现在是 0。001 变成 0001,等等。生成的文件大小为 274Mb,因此大 65Mb,但压缩到 70.2Mb,或小 4.1Mb - 占最终文件的很大一部分文件大小。

我对 gzip、bzip2 等也看到了同样的情况。添加零以获得每个字节两个 DNA 字母有助于压缩器。那么现在怎么办?我还能做些什么来帮助压缩机?我还能做些什么来获得更小的文件大小(无损)。

我认为的一个技巧是对要保存的 DNA 序列进行排序,并有一个单独的密钥可用于重新创建顺序。在 numpy 中,这是通过

完成的
my_array,key = numpy.unique(original_array, return_inverse=True)

使 my_array 成为 original_array 中唯一项的排序列表,key 成为 my_array 的索引列表,可用于重新创建original_array。理想情况下,my_array 会像 key 一样压缩得很好,但这两个文件的总和大致等于开始时未排序结构的总和。在某些情况下小一点,在其他情况下大一点 - 但没有什么值得大书特书的。

另一个想法是完全使用不同的数据结构,比如 graph/trei(仍然编码为一个结构,但每一行都是一个节点而不是一个条目),但我担心我'以错误的方式考虑压缩。我知道我不能将文件大小减小到熵的限制之外,但也许预压缩有一些秘密,比如将数据对齐字节,这是比创建较小的未压缩文件更好的途径 - 但压缩文件更大。

我不是在问 'how do you do precompression',我是在问 '预压缩是我可以了解更多的东西,如果是的话,我正在寻找的 buzzword/search 术语是什么'.

I know i can't reduce the filesize beyond the limits of entropy

但你可以!许多压缩机经常这样做。问题是(香农)熵取决于 pdf,即给定符号的概率分布。符号可以是“0”或“1”;或 A、C、T、G 和 N;或高频等位基因。每组符号都会为您提供不同的熵度量。找到正确的符号集,你就成功了。

像 LZC 这样的压缩器使用各种方法动态调整二进制字符串上的 pdf,并且很难被击败。但是,如果您对自己的数据有所了解,或许可以改进它们。

祝你好运!