La compression de données à virgule flottante
Existe-il des méthodes de compression sans perte qui peut être appliquée à virgule flottante de séries chronologiques de données, et continuera de les surpasser, de dire, d'écrire les données sous forme binaire dans un fichier et en l'exécutant à travers gzip?
Réduction de la précision peut être acceptable, mais il doit se faire d'une manière contrôlée (c'est à dire je dois être en mesure de fixer une limite sur le nombre de chiffres doit être conservé)
Je suis en train de travailler avec certains de gros fichiers de données qui sont des séries de corrélation double
s, décrivant une fonction du temps (c'est à dire les valeurs sont corrélées). Je n'ai généralement pas besoin de la pleine double
de précision, mais j'ai peut-être besoin de plus de float
.
Car il existe des méthodes sans perte pour les images/audio, je me demandais si quelque chose spécialisé existe pour cette situation.
Précisions: je suis à la recherche pour les outils pratiques plutôt que d'un article décrivant comment mettre en place quelque chose comme ça. Quelque chose de comparable à gzip en vitesse serait excellent.
- Qu'allez-vous faire avec ces données? Êtes-vous transférer? Le stockage pendant un certain temps avant de l'utiliser? Juste essayer d'utiliser moins de mémoire? Ou êtes-vous spécifiquement à la recherche d'un compact moyen de stocker des données de séries chronologiques?
- Plusieurs raisons, mais je ne suis pas sûr que ça va aider avec toutes ces personnes. 1. Je suis faible sur la mémoire, il serait utile de stocker les bits inutilisés en mémoire comprimé, tandis que la décompression seulement ce que je suis en traitement. 2. La Compression peut écart de lecture/écriture à partir de/à disque (il l'a fait pour moi, avec d'énormes fichiers de texte et gzip) 3. Oui, je suis le stockage de données compressé sur le disque (gzip maintenant).
- Pour l'instant la plupart de mes données est presque périodique, et gzip me donne un 4x compression. Je suis sûr que beaucoup mieux, c'est possible en raison des fortes corrélations dans les données.
- Vous dites, "sans perte", mais vous dites aussi que "la réduction de la précision est acceptable." Mais, la réduction de la précision c'est une perte.
- J'ai aussi dit que cela doit être fait d'une manière contrôlée, c'est à dire définir une limite sur elle. Je n'ai pas besoin tous les 15 chiffres de la double valeur de précision dans toutes les applications, mais j'ai besoin d'être en mesure de définir une garantie de la préservation par exemple, au moins 6 chiffres, ou quelque chose de similaire. Est-ce à clarifier la question? Ne soyons pas coincé polémiquer sur les détails sans importance, je pense que la question est assez claire dans ce que je recherche. Une solution qui n'est pas de réduire la précision est acceptable pour mes besoins. Une solution qui n'est pas le réduire en dessous d'un seuil réglable est également acceptable.
- Si vous savez à l'avance combien de précision, vous avez besoin de conserver, vous pouvez essayer de convertir les valeurs brutes à une représentation sous forme de chaîne. Un test rapide à l'aide de VB.Net (avec des valeurs aléatoires) montre qu'il compresse jusqu'à 45% au lieu de 150%. YMMV
- La réduction de la précision, de manière contrôlée est "la compression avec perte." "Lossless" signifie que la compression et puis la décompression des rendements exactement les mêmes données, bit par bit, comme l'original. Si le résultat n'est qu'une approximation (généralement dégradées dans certains contrôlé/délimitée façon), alors que c'est "la compression avec perte."
- Pouvez-vous laisser de côté les cheveux en les divisant @jameslarge ? Elle n'ajoute rien à la discussion. Ce type de "j'ai à droite" compulsif affirmant ne pas faire de StackOverflow un meilleur endroit. Concentrons-nous sur la solution du problème, allons-nous?
- Je me demandais si vous êtes à l'aide de C# ou C++ et si vous avez regardé LZ4? J'ai été en utilisant un LZ4 algorithme en C#, ce qui ne permet pas de fournir le plus haut niveau de compression pour nos données, mais semble être la manière la plus rapide de compression et de décompression pour le niveau de compression, il prend en charge.
- Le dialogue sur lossless et de "réduction de precisison pourrait être acceptable" est étrange, j'ai l'impression que james est mis d'analyse de la question ou quelque chose, plutôt que ce que c'est une question d'égo. J'ai lu la question "y a-lossless... ou, je pourrais être intéressé, avec perte des solutions". Je pense que c'était l'intention, et il est clair et non-problématique pour moi, mais peut-être il serait utile si vous juste ajouté "Ou" à la deuxième phrase: "Ou, à la réduction de la précision peut être acceptable, ..." et peut-être inclure le mot de perte ainsi. Ou, vous pouvez juste avoir du plaisir à hurler à jacques 🙂
- Je vois que vous vous posé une question similaire sur scicomp et obtenu quelques excellentes réponses, donc je voulais m'assurer qu'il n'y est fait référence ici: scicomp.stackexchange.com/questions/1671/...
Vous devez vous connecter pour publier un commentaire.
Vous pourriez vouloir jeter un oeil à ces ressources:
Algorithme et sa mise en Œuvre, Rapide de la Compression sans perte de Scientifiques de Données en virgule Flottante et Haut Débit de Compression de Double Précision
De Données En Virgule Flottante
Vous pourriez aussi essayer de Logluv TIFF compressés pour cette, pensé que je ne l'ai pas utilisé moi-même.
Voici quelques idées si vous voulez créer votre propre algorithme simple:
Puisque vous dites que vous avez besoin d'une précision, quelque part entre "float" et "double": vous pouvez le remettre à zéro d'un nombre quelconque de bits de poids faible dans le cas de simple et de double précision de flotteurs. La norme IEEE-754 virgule flottante chiffres sont représentés en binaire à peu près comme
seeefffffffff
, qui représente la valeursigne*1.fffffff*2^(eee).
Vous pouvez remettre à zéro le moins fraction significative (f) bits. Pour la simple précision (32 bits) flotte, il y a 23 fraction des morceaux de laquelle vous pouvez remettre à zéro jusqu'à 22. Pour la double précision (64-bit), il est de 52 et jusqu'à 51. (Si vous avez zéro tous les bits, les valeurs spéciales de NaN et de +/-inf seront perdues).
Surtout si les données représentent les valeurs décimales telles que 1.2345, cela aidera à la compression de données. C'est parce que 1.2345 ne peut pas être représenté exactement comme un fichier binaire en virgule flottante valeur, mais plutôt comme
0x3ff3c083126e978d
, ce qui n'est pas favorable à la compression de données. Hacher off le moins significatif de 24 bits, le résultat sera0x3ff3c08312000000
, qui est toujours exacte pour environ 9 chiffres après la virgule (dans cet exemple, la différence est de 1,6 e-9).Si vous faites cela sur les données brutes, puis stocker les différences entre les resultants numéros, il sera encore plus la compression de compagnie (via gzip) si les données brutes varie lentement.
Voici un exemple en C:
Et un python/numpy:
Depuis que vous demandez pour les outils existants, peut-être pdz fera l'affaire.
Possible des méthodes qui peuvent être utilisées pour floating-point de compression:
Transposer 4xN pour flotter et 8xN pour double + lz77
Mise en œuvre: Floating point de compression dans TurboTranspose
voir également d'erreur lié à la compression avec perte
Prédicteur (ex. Fini le Contexte de la Méthode) + encodage (ex. "integer compression").
Mise en œuvre: Floating point de compression dans TurboPFor
lorsque cela est possible, de convertir tous les nombres à virgule flottante en nombres entiers (ex. 1.63 -> 163),
puis utilisez entier compression
Mise en œuvre: Entier de compression
Vous pouvez tester toutes ces méthodes, avec vos données, à l'aide de la icapp outil pour linux et windows.
Une technique que l'HDF5 les gens utilisent est "brassage", où vous groupe chaque octet pour N valeurs à virgule flottante ensemble. Cela est plus susceptible de vous donner des séquences répétitives d'octets qui permettra une meilleure compression avec gzip, par exemple.
Une deuxième méthode que j'ai trouvé qui réduit considérablement la taille de gzippée de données est d'abord de convertir les données de la float16 (demi-précision) format et de retour à nouveau à float32. Ce produit beaucoup de zéros dans le flux de sortie qui peut réduire les tailles de fichier d'environ 40 à 60 pour cent après la compression. Une subtilité, c'est que le maximum de float16 valeur est assez faible, de sorte que vous pouvez l'échelle de vos données, par exemple en python
Quelques tests suggèrent que la moyenne absolue des fractions de différence entre l'entrée et la sortie de certaines données sont autour de 0.00019 avec un maximum de 0.00048. Ceci est en ligne avec les 2**11 précision de la mantisse.
Vous pouvez utiliser Holt de l'algorithme de lissage Exponentiel (qui est la prédiction basée sur l'algorithme de compression). D'abord attribuer un certain poids sur les données afin de prédire la valeur suivante.Si les données sont les mêmes,il produit beaucoup de zéros dans le MSB en effectuant l'opération XOR