data-structures - 如何以定义明确的非自定义格式编写小数
问题描述
假设我有一个传感器返回测量数据(例如每秒 6 x 50 个值)。每个值都是单精度浮点数范围内的小数。我需要将这些数据写入一个文件,然后由另一个应用程序读取该文件以进行其他操作。格式化/编码文件的最有效方法是什么?
起初我认为 CSV 是为了简单起见,但随后使用科学记数法会导致每个小数的长度为 9 个字节或更多(例如 -4,97E-03)。在大量传感器上长时间保留数据的情况下,这可能是存储限制的问题,也因为这些数据具有高熵,因此压缩没有多大帮助。
所以我在考虑将小数保存为浮点数(4 个字节)会节省大量数据,但我不知道哪些格式提供了定义明确的结构来存储浮点数表。是否有类似逗号分隔值的东西,其中值采用 IEEE754 格式,或类似的东西?我问这个是因为我想避免定义自定义格式。
解决方案
正如您所说,以人类可读的文本格式(如 CSV)编码浮点数的空间效率非常低,因为每个 32 位浮点数需要十几个字符来编码。作为测试,我生成了 100 万个随机 32 位浮点数并将它们保存为文本文件:
-5.92667373e+04
-1.10473797e+05
7.58996562e+04
3.52729886e+04
...
该文件的大小为 15,499,059 字节。但是,这样的文本文件压缩得非常好!通过 gzip 运行文件后,文件大小减少到 5,925,628 字节。这还不错,大约是将浮点数存储为二进制数据(4,000,000 字节)所需的大小的 1.5 倍。
32 位浮点数表示大约 7 位有效数字的精度,但这对于表示测量值可能过多,尤其是在已知测量值不如此精度的情况下。使用文本格式,您可以通过打印更少的有效数字来节省空间。或者,如果写入二进制数据,您可以通过向下舍入到16 位半精度浮点数或 16 位定点表示来将成本降低到一半。
正如 Eric 评论的那样,您可以直接编写原始二进制数据以及数组维度或您需要的任何其他内容,并提出您自己的临时格式。但是,如果您更愿意使用现有的标准格式,这里有几个建议:
Python numpy 库原生支持NPY 格式,并且可以表示浮点数组或任何其他可以放入 numpy 数组的内容。如果您已经在 Python 中工作,则可以使用np.load和np.save轻松读取和写入 NPY 文件。还有其他语言中的 NPY 实现,例如C++中的https://github.com/rogersce/cnpy和 Rust 中的https://docs.rs/npy/0.4.0/npy 。
FITS 格式广泛用于天文学。FITS 使用简单的二进制编码存储任意大小和维数的浮点数据数组,并且它可以在文本头字段中存储任意元数据。该格式有意简单,因此实现您自己的阅读器和编写器相对简单。
推荐阅读
- php - 在 Woocommerce 单一产品页面中获取产品类别名称和描述
- spring - Spring Boot REST API 生成 404 Not Found
- string - 检索时空格后缺少某些字符串
- android - 如何解决自定义时间选择器中的膨胀异常?
- unix - ¿我如何使用 RegExp 获取两个标签之间的所有文本,然后用另一个文本替换整个块?
- laravel - 方法 Illuminate\\Database\\Query\\Builder::frist 不存在
- android - Room 数据库是否支持实体中的布尔变量?
- video - 如何将 openRTSP 中的 MP4 文件编码优化到与 FFmpeg 相同的级别?
- list - 将值添加到列表中的所有整数
- wowza - wowza中查询字符串参数返回null