【问题标题】:Writing a numpy array to binary file with variable integer precision将numpy数组写入具有可变整数精度的二进制文件
【发布时间】:2013-06-11 12:22:28
【问题描述】:

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

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

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

【问题讨论】:

    标签: python numpy bitstring


    【解决方案1】:

    举个具体的例子:

    >>> 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?
    • 不使用那么多中间位串应该会快一点——这一切都在 join 方法中完成。实际上,对于您的方法,您当然不应该使用“位”,因为它是不可变的,因此 += 将在每次迭代时创建一个新对象。
    【解决方案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
    

    【讨论】:

      猜你喜欢
      • 2018-08-16
      • 1970-01-01
      • 2021-10-01
      • 2021-06-13
      • 2021-04-29
      • 2012-10-28
      • 1970-01-01
      • 1970-01-01
      • 2015-01-30
      相关资源
      最近更新 更多