【发布时间】:2019-10-08 15:58:55
【问题描述】:
我一直在尝试寻找一种方法来编码有限的字符串以压缩数据,并为每个字符串找到唯一的“ID”。
我有几百万个字符串,每个字符串大约有 280~300 个字符,但仅限于四个字母(A、T、C 和 G)。我想知道是否没有更简单的方法来编码它们,使用更少的内存,考虑到它们应该很容易使用“base 4”进行编码,但不知道更简单的方法是什么。我考虑过在 Python 中使用 for 循环,在其中迭代每个字符串,然后使用字典为每个字母找到正确的值,并将其乘以基数为四的值。示例:
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))
它似乎运行良好,将我的字符串编码为二进制格式。问题是我无法将encoded_number 转换为二进制。我能做的最好的就是使用这个:
binary = '{0:b}'.format(encoded_number)
虽然它返回了二进制值,但它会以字符串的形式返回。试图将其转换为二进制总是产生一个错误,因为整数的巨大尺寸的(使用实际280+字符的字符串时),作为长字符串上面将导致巨大的整数(230124923583823837719192000765784020788478094239354720336304458517780079994251890530919145486338353514167796587078005476564902583371606379793061574009099280577109729494013):
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 中执行此操作,因为它是我最熟悉的语言,也是我的代码已经使用的语言。
TL;DR,总结了我遇到的几个问题:
- 编码有限字符的最有效方法是什么 字符串? (上面的代码中有一个例子,是最好的 方式?)
- 还有其他压缩字符串的方法吗? 与有限字符的编码一起使用,以进一步 压缩数据?
- 大整数(4^300)能否转换成 二进制而不导致溢出?如何?
- 将二进制值、数字或有限字符串(在这种情况下基本相同,因为我正在尝试将一个转换为另一个)转换为小而简洁的字符串(用户可读,所以越小越好)
【问题讨论】:
-
什么,正是抛出了这个错误:
OverflowError: cannot fit 'int' into an index-sized integer? -
欢迎来到 StackOverflow。请按照您创建此帐户时的建议阅读并遵循帮助文档中的发布指南。 Minimal, complete, verifiable example 适用于此。在您发布 MCVE 代码并准确说明问题之前,我们无法有效地帮助您。我们应该能够将您发布的代码粘贴到文本文件中并重现您指定的问题。您发布的代码中没有任何内容会引发您发布的错误片段。
-
你在二进制输入/输出方面研究了什么?看来您的问题在于写作,而不是转换。您未能发布该代码。
-
抱歉,已编辑问题。我只是想使用'bytes'类:bytes(encoded_number)
标签: python string encoding character-encoding compression