【发布时间】:2013-06-11 12:22:28
【问题描述】:
我想将一个 numpy 数组写入二进制文件,但我想对整数使用非标准大小编码。例如,一些 int 数组将作为 3 位整数写入文件,一些为 7 位,一些为 13 位...
我看到有一个 numpy 方法 tofile() 但是它只适用于给定的数组 dtypes,它们是 int8、int16、int32 等。(Reference)
如何将其写入位长可变的文件?
【问题讨论】:
我想将一个 numpy 数组写入二进制文件,但我想对整数使用非标准大小编码。例如,一些 int 数组将作为 3 位整数写入文件,一些为 7 位,一些为 13 位...
我看到有一个 numpy 方法 tofile() 但是它只适用于给定的数组 dtypes,它们是 int8、int16、int32 等。(Reference)
如何将其写入位长可变的文件?
【问题讨论】:
举个具体的例子:
>>> 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 语言实现的,应该能够很好地处理这个问题。
【讨论】:
bits 而不是bitstreams?
+= 将在每次迭代时创建一个新对象。
我已经使用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
【讨论】: