我有以下字符串,我想对其进行霍夫曼编码并有效地存储到一个位数组中:
>>> print sequence
GTCAGGACAAGAAAGACAANTCCAATTNACATTATG|
中符号的频率为sequence
:
>>> print freqTuples
[(0.40540540540540543, 'A'), (0.1891891891891892, 'T'), (0.16216216216216217, 'C'), (0.16216216216216217, 'G'), (0.05405405405405406, 'N'), (0.02702702702702703, '|')]`
我将其翻译成霍夫曼代码字典:
>>> print codeDict
{'A': '1', 'C': '010', 'G': '001', 'N': '0110', 'T': '000', '|': '0111'}
然后,我使用 Pythonbitstring
包将字符串逐个字符地转换为BitArray
类的实例,我称之为bitArray
,其中包含用其各自的霍夫曼代码编码的每个字符的位:
>>> print bitArray.bin
0b001000010100100110101100111100110101101100000100101100000001101010100000010000010111
这是以字节为单位的位数组:
>>> print bitArray.tobytes()
!I\254\363[^D\260^Z\240Ap
我必须使用tobytes()
而不是bytes
,因为我生成的位数组不会均匀地分成 8 位段。
当我计算BitArray
表示的存储效率(位数组和输入字符串的大小之比)时,我得到的性能比不编码输入字符串时更差:
>>> sys.getsizeof(bitArray.tobytes()) / float(len(sequence))
1.2972972973
我是否正确测量存储效率?(如果我对更长的输入字符串进行编码,这个比率会提高,但它似乎接近 0.28 左右的渐近极限。我想确认这是否是衡量事物的正确方法。)
编辑
以下两种方法产生不同的答案:
>>> print len(bitArray.tobytes()) / float(len(mergedSequence))
0.297297297297
>>> print bitArray.len / (8.*len(mergedSequence))
0.283783783784
我不确定该相信哪个。但是在将数据写入存储的过程中,我认为我需要字节表示,这使我倾向于选择第一个结果。