如何压缩大量类似的双打?

Han*_*etz 4 compression

我想在内存中存储数十亿(10 ^ 9)的双精度浮点数并节省空间.这些值按数千个有序集合(它们是时间序列)进行分组,在一个集合中,我知道值之间的差异通常不大(与其绝对值相比).而且,彼此越接近,差异相对小的概率越高.

完美契合将是delta编码,其仅存储每个值与其前任的差异.但是,我想随机访问数据的子集,所以我不能依赖于按顺序完成整个集合.因此,我使用增量到一个集合范围的基线,产生增量,我预计它将在绝对值的10%到50%之间(大部分时间).

我考虑过以下方法:

  • 将较小的值除以较大的值,得到一个介于0和1之间的值,该值可以存储为某个固定精度的整数加一位,用于记住哪个数除以哪个.这是相当简单的并且产生令人满意的压缩,但不是无损方法,因此仅是次要选择.
  • 对这两个值的IEEE 754二进制64编码表示进行异或,并在指数的开头和尾数加上不同的剩余比特存储长的零延伸的长度.在这里我很不确定如何判断压缩,虽然我认为在大多数情况下它应该是好的.

有没有标准的方法来做到这一点?我上面的方法可能有什么问题?您自己看过或使用过哪些其他解决方案?

S.L*_*ott 9

很少有双精度数的所有位都有意义.

如果您有数十亿个值是某些测量值的结果,请找到测量设备的校准和误差.量化值,以便只使用有意义的位.

通常,您会发现只需要16位的实际动态范围.您可以将所有这些压缩为保留所有原始输入的"short"数组.

使用简单的"Z-score技术",其中每个值实际上是标准偏差的有符号部分.

因此,具有m的均值和s的标准偏差的一系列样本被转换成一堆Z得分.正常的Z-score转换使用double,但您应该使用该double的定点版本. s/1000或s/16384或者只保留数据实际精度的东西,而不是最后的噪声位.

for u in samples:
    z = int( 16384*(u-m)/s )

for z in scaled_samples:
    u = s*(z/16384.0)+m
Run Code Online (Sandbox Code Playgroud)

您的Z分数保留了令人愉快的易于使用的与原始样本的统计关系.


假设您使用带符号的16位Z分数.你有+/- 32,768.将此缩放16,384,您的Z分数的有效分辨率为0.000061十进制.

如果你使用签名的24但Z分数,你有+/- 800万.按比例缩放4,194,304,你的分辨率为0.00000024.

我非常怀疑你有这种准确的测量设备.此外,作为滤波器,校准或降噪的一部分而进行的任何算术可能由于在算术期间引入的噪声比特而减小有效范围.一个经过深思熟虑的除法运算符可以使你的许多小数位数不过是噪音.