Compression 如何压缩大量类似的双精度?

Compression 如何压缩大量类似的双精度?,compression,Compression,我想在内存中存储数十亿(10^9)的双精度浮点数并节省空间。这些值被分组在数千个有序的集合中(它们是时间序列),在一个集合中,我知道值之间的差异通常不大(与它们的绝对值相比)。而且,彼此越接近,差异相对较小的概率越高 一个完美的匹配是delta编码,它只存储每个值与其前一个值之间的差异。然而,我希望随机访问数据的子集,所以我不能依赖于按顺序遍历一个完整的集合。因此,我使用delta来设置一个宽泛的基线,生成delta,我希望它在绝对值的10%到50%之间(大多数时候) 我曾考虑过以下方法: 将

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

一个完美的匹配是delta编码,它只存储每个值与其前一个值之间的差异。然而,我希望随机访问数据的子集,所以我不能依赖于按顺序遍历一个完整的集合。因此,我使用delta来设置一个宽泛的基线,生成delta,我希望它在绝对值的10%到50%之间(大多数时候)

我曾考虑过以下方法:

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

有没有标准的方法可以做到这一点?上述方法可能存在哪些问题?您还见过或使用过哪些其他解决方案?

如果您知道一组双精度数具有相同的指数,则可以存储指数一次,并且只存储每个值的尾数。

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

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

通常,你会发现你只需要16位的实际动态范围。您可能可以将所有这些压缩到保留所有原始输入的“short”数组中

使用一个简单的“Z分数技术”,其中每个值实际上是标准偏差的有符号分数

所以一系列平均值为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
您的Z分数与原始样本保持了愉快的、易于处理的统计关系


假设您使用有符号的16位Z分数。你有+/-32768。将其缩放16384,您的Z分数的有效分辨率为0.000061十进制

如果使用带符号的24但Z分数,则为+/-800万。将其缩放4194304,分辨率为0.00000024


我很怀疑你们有这么精确的测量装置。此外,作为滤波器、校准或噪声降低的一部分进行的任何算法可能会由于在算法期间引入的噪声比特而减小有效范围。一个考虑不周的除法运算符可能会使许多小数点只产生噪音。

无论您选择什么压缩方案,通过将数据压缩成固定大小的块,并在每个块前加一个包含解压所需的所有数据的头,您可以将其与需要执行任意搜索的问题分离(例如,对于增量编码方案,块将包含以某种方式编码的增量,该方式利用其较小的幅度使其占用较少的空间,例如,指数/尾数、转换为定点值、霍夫曼编码等的位数较少;而头是单个未压缩的样本);然后,查找就变成了一个便宜地选择合适的块,然后对其进行解压缩的问题


如果压缩比变化太大,以至于在填充压缩数据以生成固定大小的块时浪费了大量空间,则可以构建压缩数据中的偏移目录,并在其中记录解压所需的状态。

感谢您将Z分数作为我尝试使用的概括我的第一种方法。不幸的是,我不能对传入数据中的噪声做任何假设,因为实际的物理源在精度上差异很大,而且对数据精度的要求也取决于使用我的软件的应用程序。