Comprimir datos de coma flotante

26

¿Existen herramientas diseñadas específicamente para comprimir datos científicos de coma flotante?

Si una función es fluida, obviamente existe una gran correlación entre los números que representan esa función, por lo que los datos deberían comprimirse bien. Sin embargo, los datos binarios de coma flotante binaria no se comprimen tan bien. Me pregunto si hay un método desarrollado específicamente para comprimir datos de coma flotante.

Requisitos:

  • Ya sea compresión sin pérdidas o la posibilidad de especificar un número mínimo de dígitos para retener (para algunas aplicaciones doublepuede ser más de lo que necesitamos mientras que floatpuede no tener suficiente precisión).

  • Herramienta de trabajo bien probada (es decir, no solo un documento que describe un método teórico).

  • Adecuado para comprimir datos numéricos 1D (como una serie de tiempo)

  • Multiplataforma (debe funcionar en Windows)

  • Debe ser rápido, preferiblemente no mucho más lento que gzip. Descubrí que si tengo los números almacenados como ASCII, comprimir el archivo puede acelerar la lectura y el procesamiento (ya que la operación podría estar vinculada a E / S).

Especialmente me gustaría saber de personas que realmente han utilizado una herramienta de este tipo.

Szabolcs
fuente
Esto se inspiró en parte en la existencia de FLAC , lo que sugiere que un método especializado debería funcionar (¿mucho?) Mejor que gzip.
Szabolcs
Estoy mirando esto ahora.
Szabolcs
Ordenado. Voy a darle un giro a este.
meawoppl

Respuestas:

22

Prueba Blosc . En muchos casos es más rápido que la memcopia . Piense en eso por un segundo. . . malvado.

Es súper estable, altamente investigado, multiplataforma y funciona como un campeón.

meawoppl
fuente
oh wow, esto es realmente genial (¡y nuevo para mí!)
Aron Ahmadia
El enlace está roto. ¿Alguna posibilidad de que sepa dónde está ahora?
Alexis Wilke
1
@AlexisWilke Arreglé el enlace. Fue el primer resultado en una búsqueda en Google de Blosc.
Doug Lipinski
1
Blosc es quizás rápido pero su tasa de compresión en matrices flotantes es un desastre. Con la mejor compresión que ofrece, resulta en aproximadamente el 98% del tamaño original. Gracias por el consejo en cualquier caso.
La compresión en matrices flotantes depende en gran medida del contenido. Sospecho que hay poca información (estructurada) en los bits que está comprimiendo. Además, ¡blosc todavía está en desarrollo activo 5 años después!
meawoppl
7

Obtuve buenos resultados con HDF5 y su filtro GZIP.

El HDF5 también proporciona un filtro SZIP que logra mejores resultados para algunos conjuntos de datos científicos.

En mi experiencia, la elección de las compresiones depende en gran medida del tipo de datos y la evaluación comparativa es probablemente la única forma de hacer una buena elección.

Por cierto, los filtros de terceros para HDF5 incluyen BLOSC, BZIP2, LZO, LZF, MAFISC.

f3lix
fuente
Gracias por la respuesta! No he usado mucho HDF5. ¿Es correcto que usar el filtro gzip con el formato HDF5 me dé la misma relación de compresión que escribir todo el número en un archivo binario plano y ejecutarlo a través de gzip? (Ignore la posible conveniencia / inconveniencia de usar HDF5 por ahora.) Con respecto a SZIP, ¿está optimizado de alguna manera para los conjuntos de datos de punto flotante? (Tengo curiosidad y esto no está claro al hojear la página que ha vinculado). La página dice que la principal ventaja de SZIP es la velocidad. GZIP también es bastante ágil (por lo general, la descompresión de gzip es insignificante para mí).
Szabolcs
Un archivo binario plano comprimido probablemente será más pequeño que un archivo HDF5 con filtro gzip, porque HDF5 es más que datos sin procesar. A veces, el preprocesamiento con un filtro aleatorio puede mejorar los resultados de gzip. Pero tiene razón, las ventajas son de hecho más conveniencia. Con HDF5 me resulta fácil cambiar el filtro de compresión (probar diferentes configuraciones) y HDF5 proporciona funciones para acceder a subconjuntos de sus datos (intervalos en series de tiempo).
f3lix
1
Si sigue esta ruta, consulte pyTables . Hace que lo anterior sea solo un par de líneas de código. Mantenido (anteriormente al menos) por el autor Blosc.
meawoppl
6

[-1,1]

Dependiendo de la función subyacente, es posible que pueda ajustar los datos a una forma funcional sin error, lo que requiere menos coeficientes para describir la forma funcional que el punto de datos (lo que lleva a la compresión). Existen resultados de error para algunos de estos métodos, aunque no sé si alguno de ellos le dará a priori (o límites o estimaciones a a posteriori ) sobre el error.

También puede mirar métodos desarrollados específicamente para la compresión de números de coma flotante, como FPC y algoritmos relacionados. Vea los documentos aquí , aquí , aquí , aquí y aquí , junto con una página web que contiene el código fuente antiguo aquí .

Geoff Oxberry
fuente
En realidad, estoy interesado en herramientas listas para usar similares a gzip que no requieren ningún trabajo de mi parte, especialmente no desarrollar y ajustar mi propio método. Además, sería ventajoso tener un método que no requiera leer todo en la memoria antes de descomprimirlo, ya que podría tener archivos de datos muy grandes que pueden procesarse secuencialmente (esto funciona con gzip, pero no si uso un Fourier transformar, a menos que yo mismo corte los datos en fragmentos, lo que complica aún más todo) Algo que asume que mi archivo de datos es solo una serie de dobles binarios sería excelente.
Szabolcs
También se trata de transformaciones 1: 1 que no son realmente técnicas de compresión. Se pueden usar para crear datos con los que un algoritmo de compresión ingenuo puede mejorar, pero no es una solución independiente.
meawoppl
Algunos de estos métodos forman la base matemática para los algoritmos de compresión utilizados en el procesamiento de señales, que fue la idea detrás de la respuesta. Estas transformaciones generalmente no son 1: 1 excepto en circunstancias especiales.
Geoff Oxberry
3

HDF5 puede usar un algoritmo de "mezcla" en el que los bytes para N números de coma flotante se reorganizan de modo que los primeros bytes de los N números sean primero, luego el segundo, y así sucesivamente. Esto produce mejores relaciones de compresión después de aplicar gzip, ya que es más probable que produzca secuencias más largas del mismo valor. Vea aquí algunos puntos de referencia .

xioxox
fuente
1

SZ (desarrollado por Argonne en 2016) podría ser una buena opción.

SZ: Compresor de datos de punto flotante limitado por error rápido para aplicaciones científicas https://collab.cels.anl.gov/display/ESR/SZ

Linda
fuente
¿Por qué crees que podría ser una buena opción? ¿Cuáles son sus capacidades en comparación con otras técnicas de compresión?
Paul
1

Métodos posibles, que se pueden usar para la compresión de punto flotante:

  • Transposición 4xN para flotación y 8xN para doble + lz77
    Implementación: Compresión de coma flotante en TurboTranspose,
    consulte también compresión con pérdida limitada por errores

  • Predictor (ej. Método de contexto finito) + codificación (ej. "Compresión de enteros").
    Implementación: Compresión de coma flotante en TurboPFor
    incluyendo compresión especial para series de tiempo.

  • cuando sea posible, convierta todos los números de coma flotante a enteros (ej. 1.63 -> 163), luego use la compresión de enteros

  • Puede probar todos estos métodos con sus datos utilizando la herramienta icapp para Linux y Windows.

Powturbo
fuente
1

Hemos estado usando ZFP con HDF5 para nuestros datos de imágenes médicas. Está hecho para compresión con pérdida de coma flotante.

Lo estamos ejecutando literalmente en todo y tenemos más de 40 TB de datos almacenados (¡y en uso!). Es lo suficientemente rápido como para guardar nuestros datos en tiempo real, y podemos especificar la precisión requerida, por lo que si bien el formato es con pérdidas, no vemos diferencias en nuestros resultados finales.

LKlevin
fuente
0

Si una función es fluida, obviamente existe una gran correlación entre los números que representan esa función, por lo que los datos deberían comprimirse bien.

Quizás el formato que necesita necesita almacenar solo las compensaciones del valor al valor vecino.

Alternativamente, tal vez podría hacer uso del dominio de frecuencia, tal vez incluso guardar estos valores como un archivo de audio sin pérdida, como "flac lossless", ya que requiere algunas de las mismas propiedades para un sonido.

Sin embargo, voy a adoptar un enfoque diferente para intentar responder la pregunta que espero pueda ser de alguna ayuda. Como lo que está diciendo también es que la longitud mínima de descripción para representar estos datos es menor que proporcionar todos los puntos de datos.

https://en.wikipedia.org/wiki/Minimum_description_length

Efectivamente, un programa, código de computadora, es un buen ejemplo. Y si no le importa que algo sea principalmente el trabajo de datos mediante la ejecución, y también el código, puede comprimir sus valores de coma flotante en algo como una función o fórmula.

Hacer esto particularmente bien automáticamente, y en una cantidad realista de cómputo, es más que difícil. Sin embargo, Wolfram Language proporciona alguna funcionalidad para intentar esto:

https://reference.wolfram.com/language/ref/FindSequenceFunction.html https://reference.wolfram.com/language/ref/FindGeneratingFunction.html https://reference.wolfram.com/language/ref/FindFormula. html

https://reference.wolfram.com/language/ref/RSolve.html

alan2here
fuente
0

¿Por qué no solo guardar float32 / float16? En numpy,

A.astype( np.float32 )  # 100M: 200 msec imac
A.astype( np.float16 )  # 100M: 700 msec

Esto no funcionará si estás simulando el efecto Mariposa en la teoría del caos, pero son comprensibles, portátiles, "no requieren ningún trabajo de mi parte". Y la compresión 2: 1/4: 1 sobre float64 es difícil de superar :)

Notas:

"El tipo de matriz float16 no es compatible con np.linalg"; tendrás que expandirlo a 32 o 64 después de leerlo.

Para ver cómo difieren los parámetros de punto flotante,

import numpy as np
for f in [np.float64, np.float32, np.float16]:
    print np.finfo(f)

Para una gráfica de un caso de prueba trivial que compara el flotador 64 32 y 16, vea aquí .

denis
fuente