有效地压缩numpy数组

Bas*_*asj 14 python compression arrays numpy lossless-compression

我在保存到磁盘时尝试了各种方法进行数据压缩numpy arrays.

这些一维阵列包含一定采样率的采样数据(可以使用麦克风录制声音,或使用任何传感器进行任何其他测量):数据基本上是连续的(在数学意义上;当然,采样后它现在是离散数据) .

我试过HDF5(h5py):

f.create_dataset("myarray1", myarray, compression="gzip", compression_opts=9)
Run Code Online (Sandbox Code Playgroud)

但这很慢,压缩比不是我们所能期望的最好.

我也尝试过

numpy.savez_compressed()
Run Code Online (Sandbox Code Playgroud)

但是再一次,它可能不是这种数据的最佳压缩算法(如前所述).

对于numpy array这样的数据,你会选择什么来获得更好的压缩比?

(我考虑过无损FLAC(最初是为音频而设计),但是有一种简单的方法可以在numpy数据上应用这样的算法吗?)

Alb*_*ert 14

我现在应该做什么:

import gzip
import numpy

f = gzip.GzipFile("my_array.npy.gz", "w")
numpy.save(file=f, arr=my_array)
f.close()
Run Code Online (Sandbox Code Playgroud)

  • 节省您的点击:`f = gzip.GzipFile('file.npy.gz', "r"); np.load(f)` (6认同)
  • 并重新加载它:http://stackoverflow.com/questions/42849821/how-to-recover-a-numpy-array-from-npy-gz-file (2认同)

Ale*_*x I 13

  1. 噪音是不可压缩的.因此,无论压缩算法如何,您拥有的任何噪声数据都将以1:1的比例进入压缩数据,除非您以某种方式丢弃它(有损压缩).如果每个样本的24位有效位数(ENOB)等于16位,则剩余的24-16 = 8位噪声会将您的最大无损压缩比限制为3:1,即使您的(无噪声)数据也是如此是完全可压缩的.非均匀噪声可压缩到不均匀的程度; 你可能想看一下噪声的有效熵来确定它是如何可压缩的.

  2. 压缩数据基于对其进行建模(部分是为了消除冗余,但也部分是为了将噪声与噪声分离并丢弃噪声).例如,如果您知道您的数据带宽限制在10MHz并且您在200MHz采样,则可以进行FFT,将高频归零,并仅存储低频系数(在此示例中:10:1压缩).有一个称为"压缩感应"的整个领域与此相关.

  3. 一个实用的建议,适用于多种合理连续的数据:去噪 - >带宽限制 - > delta压缩 - > gzip(或xz等).降噪可以与带宽限制相同,也可以像运行中位数那样使用非线性滤波器.使用FIR/IIR可以实现带宽限制.Delta压缩只是y [n] = x [n] - x [n-1].

编辑插图:

from pylab import *
import numpy
import numpy.random
import os.path
import subprocess

# create 1M data points of a 24-bit sine wave with 8 bits of gaussian noise (ENOB=16)
N = 1000000
data = (sin( 2 * pi * linspace(0,N,N) / 100 ) * (1<<23) + \
    numpy.random.randn(N) * (1<<7)).astype(int32)

numpy.save('data.npy', data)
print os.path.getsize('data.npy')
# 4000080 uncompressed size

subprocess.call('xz -9 data.npy', shell=True)
print os.path.getsize('data.npy.xz')
# 1484192 compressed size
# 11.87 bits per sample, ~8 bits of that is noise

data_quantized = data / (1<<8)
numpy.save('data_quantized.npy', data_quantized)
subprocess.call('xz -9 data_quantized.npy', shell=True)
print os.path.getsize('data_quantized.npy.xz')
# 318380
# still have 16 bits of signal, but only takes 2.55 bits per sample to store it
Run Code Online (Sandbox Code Playgroud)


小智 5

通过压缩保存 HDF5 文件可以非常快速和高效:这完全取决于压缩算法,以及您是否希望在保存时或读回时快速,或两者兼而有之。当然,正如上面所解释的,数据本身也是如此。GZIP 往往介于两者之间,但压缩比较低。BZIP2 双方都很慢,但比率更好。BLOSC 是我发现压缩率很高且两端速度都很快的算法之一。BLOSC 的缺点是它并未在 HDF5 的所有实现中实现。因此你的程序可能不可移植。您总是需要进行(至少是一些)测试来选择最适合您需求的配置。