在Python中用有限字符压缩/编码字符串

2024-03-28 22:58:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直在尝试找到一种方法来编码有限的字符串,以便压缩数据,并为每个字符串找到唯一的“id”。在

我有几百万个字符串,每个字符串大约280~300个字符,但仅限于四个字母(A、T、C和G)。我想知道是否有一种更简单的方法来编码它们,使用更少的内存,考虑到它们应该很容易地使用“基4”进行编码,但不知道什么是更简单的方法。我考虑过在Python中使用for循环,在那里我会迭代每个字符串,然后使用字典为每个字母找到正确的值,并将其乘以基数为4的值。示例:

base_dict = {
    'A' : 0,
    'T' : 1,
    'C' : 2,
    'G' : 3
} # These are the four bases of DNA, each assigned a different numeric value

strings_list = [ 
'ATCG', 
'TGGGGAATATTGCACAATGGGGGAAACCCTGATGCAGCGACGCCGCGTGAGCGAAGAAGTATTTCGGTATGTAAAGCTCTATCAGCAGGGAAGAAAATGACGGTACCTGACTAAGAAGCCCCGGCTAACTACGTGCCAGCAGCCGCGGTAATACGTAGGGGGCAAGCGTTATCCGGATTTACTGGGTGTAAAGGGAGCGTAGACGGGACAGCAAGTCTGATATGAAAGGCGGGGGCTCAACCCCCGGACTGCATTGGAAACTGCTGGCCTGGAGTACCGGAGG',
'GGGGGGGGGG' 
] # A few sample DNA sequences

for string in strings_list:
    encoded_number = 0
    for i in range(len(string)):
        letter = string[i]
        encoded_number += (4**i) * base_dict[letter]
    print('String {} = {}'.format(string, encoded_number))

它似乎工作得很好,把我的字符串编码成二进制格式。问题是我无法将编码的_数转换成二进制。我能做的就是用这个:

^{pr2}$

但是尽管它返回了二进制值,但它会以字符串的形式返回。尝试将其转换为二进制总是会产生错误,因为整数的大小非常大(当使用实际的280+个字符字符串时),因为上面的长字符串将产生一个巨大的整数(230124923583823837719192000765784020788487809429354720336304458517780079994251890530919145486338353514167796587078005476499025833716037979306157409099280577109729494013):

bytes(encoded_number) # trying to turn the encoded number into bytes
OverflowError: cannot fit 'int' into an index-sized integer

我想知道这是不是像这样对有限的字符串进行编码的最有效的方法,或者是否有更好的方法,以及是否有其他方法可以更有效地压缩这些数据,同时还可以将最后的数字/二进制数反转回字符串中。另外,我是否可以将其转换为二进制格式,而不是整数或字符串?这样做有助于保存数据吗?在

另外,将人类可读值的整数/二进制值缩减为一个新的、较短的字符串)的最简洁的方法是什么?使用整数或二进制文件似乎可以节省数据,而且我可以用更少的内存存储这些字符串(同时也可以更快地传输数据),但是如果我想创建简洁的用户可读字符串,最好的选择是什么?有没有什么方法我可以编码回一个字符串,但利用整个ASCII表,以便使用更少的字符?在

如果能够将300个字符的字符串缩减成更小的86个字符的字符串,这将非常有用(考虑到ASCII表有128个字符可用,4^300~=128^86)。在

我正试图用Python来实现这一点,因为Python是我最熟悉的语言,同时也是我的代码所使用的语言。在

TL;DR,总结了我遇到的几个问题:

  1. 对有限字符编码最有效的方法是什么 串?(上面的代码中有一个例子,这是最好的吗 是吗?)在
  2. 有没有其他方法可以压缩字符串 与有限字符编码一起使用,以进一步 压缩数据?在
  3. 大整数(4^300)可以转换成 没有导致溢出的二进制文件?怎样?在
  4. 把二进制值、数字或有限的字符串(在这种情况下基本上是一样的,因为我试图将其中一个转换成另一个)转换成小而简洁的字符串(用户可读,所以越小越好)的最有效方法是什么

Tags: 数据方法内存字符串number编码forbase
1条回答
网友
1楼 · 发布于 2024-03-28 22:58:18

你所做的转换是显而易见的:因为4是2的幂,所以对于均匀分布的序列来说,转换成二进制的过程是非常紧凑的。你只需要用它的2位序列来表示每个字母,你就完成了转换。在

你的问题似乎是存储结果。最短的更改可能会升级您的代码using ^{} properly。在

另一种方法是将字符串分成8个字母的块,将每个块变成一个32位整数;然后写出整数序列(二进制)。在

另一种方法是忘记整个转换过程;将字符串输入到系统的压缩算法中,这将利用频繁的氨基酸。在

注意:您的转换将丢失前导零,例如“AAAAGCTGA”;这将重新构成“GCTGA”。您需要包括预期的字符串长度。在


要执行简单的chunk convert方法,请参阅我提供的链接。在

对于压缩方法,请研究压缩(根据发布指南,我们假设您在发布之前已经做过压缩)。在Linux上,使用操作系统提供的文件压缩(可能是gzip)。在

另一种可能是,如果至少有两种氨基酸没有出现在数据中,则对其他三元组进行编码,并使用base62(在浏览器中搜索文档),这将使用所有字母数字字符以文本可读的形式进行编码。在

相关问题 更多 >