2

我想将一个 numpy 数组写入二进制文件,但我想对整数使用非标准大小编码。例如,一些 int 数组将作为 3 位整数写入文件,一些为 7 位,一些为 13 位...

我已经看到有一个 numpy 方法tofile(),但是它仅适用于给定的数组 dtypes,它们是 int8、int16、int32 等。(参考)

我如何将它写入具有可变位长的文件?

4

2 回答 2

2

bitstring我已经使用该模块为此编写了一个方法。

def int_array_to_bitstream(int_array, precision):
    int_list = int_array.astype(int).tolist()
    bits = ''
    for integer in int_array:
        bits += bitstring.BitStream(int=integer, length=precision)
    return bits

它获取 numpy 数组的每个成员,并使用precision位数将其转换为整数的二进制表示。这正是我想要的,但是它会减慢使用速度。

我正在寻找一种更快的方法来实现同样的目标,无论是作为一种全新的方法还是通过改进当前的方法

更新 14.6。

尝试使用另一个答案中的方法。

def int_array_to_bitstream_ver2(int_array, precision):
    bits = bitstring.BitStream().join(bitstring.BitStream(uint=integer, length=precision) for integer in int_array)
    return bits

速度差异很小。对于int_array = arange(100000)precision = 24

int_array_to_bitstream -> 5.958 sec
int_array_to_bitstream_ver1 -> 5.614 sec
于 2013-06-11T12:22:28.393 回答
2

举一个比特串的具体例子:

>>> from bitstring import Bits
>>> a = [3,1,2,6,4,10]  # some unsigned integers to encode
>>> p = 5               # number of bits of precision to use

现在从每个整数创建 5 位位串并将它们连接在一起:

>>> b = Bits().join(Bits(uint=x, length=p) for x in a)
>>> b
Bits('0b000110001000001001100010001010')

可以将其转换为字节,但请注意,如果需要,它将用零位填充到字节边界。当写入一个文件时,你总是会有一个整数字节,就像文件系统的工作方式一样:

>>> b.tobytes()
'\x18\x82b('    

要再次对其进行解码,有多种选择,但由于所有内容的长度都相同,因此该cut方法很有用:

>>> [x.uint for x in b.cut(p)]
[3, 2, 1, 6, 4, 10]

See the docs for more information. In terms of efficiency it should be pretty good for pure Python. If you really need more speed then try the bitarray module instead, which is implemented in C and should be able to handle this problem equally well.

于 2013-06-11T13:22:37.997 回答