将numpy数组写入具有可变整数精度的二进制文件

时间:2013-06-11 12:22:28

标签: python numpy bitstring

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

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

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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

给出一个具有bitstring的具体例子:

>>> 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]

有关详细信息,请参阅the docs。就效率而言,纯Python应该是相当不错的。如果你真的需要更高的速度,那么尝试使用bitarray模块,它在C中实现,应该能够同样很好地处理这个问题。