位级压缩

时间:2016-04-21 14:21:43

标签: python compression

我计划在文件上存档数小时的传感器数据。对于此传感器,分辨率(使用的位数)是完全已知的:22位

我的第一次尝试是将一连串的22位值连接起来,作为比特流连接。

它工作得很好,特别是当信号很复杂时。 但是,当信号高度可压缩时,我发现将项目填充到下一个8的倍数会更有趣。

例如:

high_res_sinus = [int(math.sin(i) * 0x3FFFFF) & 0x3FFFFF for i in range(10000)]
low_res_sinus = [int(math.sin(i) * 0x3) & 0x3FFFFF for i in range(10000)]

在这里,high_res_sinuslow_res_sinus

更难压缩(使用gzip)
# size before -> after gzip compression (ratio)
high_res_sinus:22 bits: 27500 -> 27528 (100.1 %) # 22 bits
high_res_sinus:24 bits: 30000 -> 29300 (97.7 %) # same, padded to 24 bits
low_res_sinus:22 bits: 27500 -> 1104 (4.0 %) # 22 bits
low_res_sinus:24 bits: 30000 -> 374 (1.2 %) # same, padded to 24 bits
low_res_sinus:32 bits: 40000 -> 338 (0.8 %) # same, padded to 32 bits, even better !

https://code.activestate.com/recipes/580649-nbitarray/

对于high_res_sinus 22位值,连接,是最佳选择,未压缩! 但对于low_res_sinus,压缩填充版本要好得多。

您是否知道压缩器可以将分辨率设置为与模8不同的值? 你有更好的建议吗?

修改

关于更好的建议:我发现hdf5与mafisc过滤器的组合对于传感器数据非常有效。即使我喜欢重新发明轮子:)

1 个答案:

答案 0 :(得分:1)

通常,下一个传感器样本的良好模型是最后一个传感器样本。您应该查看差异样本然后压缩。您按原样发送第一个样本。每个后续样本作为该样本减去前一个样本发送。为了帮助压缩,您可以将每个差异存储为可变数量的字节,使用每个字节的高位来指示是否存在另一个字节。理想情况下,大多数样本最终都是一个字节。然后你可以应用deflate(gzip)或其他一些无损压缩器。

如果这是所有位,则编码是差值的最低有效7位,高位作为1,如果下一个字节中有更多位,则编码为0。依此类推,直到你得到所有的位,以高位为止。