5

一部のバイナリ イメージ データをシーケンス if ビットとしてエンコード/圧縮したいと考えています。(このシーケンスは、一般に、整数の標準整数型にうまく収まらない長さになります。)

スペースを無駄にせずにこれを行うにはどうすればよいですか? (ビットのシーケンスが「良い」長さでない限り、最後に常に少量の[<1バイト]の残りのスペースが必要になることを認識しています。)

FWIW、エンコードするシンボルごとに最大で 3 ビットが必要になると推定しています。Python には、この種の作業用の組み込みツールがありますか?

4

3 に答える 3

6

非常に便利な組み込み機能はありませんが、このために設計されたbitstringbitarrayなどのサードパーティ モジュールがあります。

from bitstring import BitArray
s = BitArray('0b11011')
s += '0b100'
s += 'uint:5=9'
s += [0, 1, 1, 0, 1]
...
s.tobytes()

一連の 3 ビット数値 (つまり、範囲 0->7) を結合するには、次のように使用できます。

>>> symbols = [0, 4, 5, 3, 1, 1, 7, 6, 5, 2, 6, 2]
>>> BitArray().join(BitArray(uint=x, length=3) for x in symbols)
BitArray('0x12b27eab2')
>>> _.tobytes()
'\x12\xb2~\xab '

関連する質問:

于 2011-02-21T12:51:21.907 に答える
3

bz2でシーケンス全体を単純に圧縮してみましたか? シーケンスが長い場合は、bz2.BZ2Compressor を使用してチャンク処理を許可する必要があります。それ以外の場合は、全体で bz2.compress を使用します。圧縮はおそらく理想的ではありませんが、まばらなデータを扱う場合、通常は非常に近くなります。

それが役立つことを願っています。

于 2011-02-21T12:59:11.023 に答える
2

シンボルから 3 ビット文字列へのマッピングがあるため、bitarray はシンボルのリストをビット配列との間でエンコードおよびデコードする優れた仕事をします。

from bitarray import bitarray
from random import choice

symbols = {
    '0' : bitarray('000'),
    'a' : bitarray('001'),
    'b' : bitarray('010'),
    'c' : bitarray('011'),
    'd' : bitarray('100'),
    'e' : bitarray('101'),
    'f' : bitarray('110'),
    'g' : bitarray('111'),
}

seedstring = ''.join(choice(symbols.keys()) for _ in range(40))

# construct bitarray using symbol->bitarray mapping
ba = bitarray()
ba.encode(symbols, seedstring)

print seedstring
print ba

# what does bitarray look like internally?
ba_string = ba.tostring()
print repr(ba_string)
print len(ba_string)

版画:

egb0dbebccde0gfdfbc0d0ccfcg0acgg0ccfga00
bitarray('10111101000010001010101001101110010100... etc.
'\xbd\x08\xaanQ\xf4\xc9\x88\x1b\xcf\x82\xff\r\xee@'
15

この 40 個のシンボル リスト (120 ビット) が 15 バイトのビット配列にエンコードされることがわかります。

于 2011-02-21T14:25:39.170 に答える