Kompresowanie danych zmiennoprzecinkowych

26

Czy są jakieś narzędzia zaprojektowane specjalnie do kompresji danych naukowych zmiennoprzecinkowych?

Jeśli funkcja jest płynna, istnieje oczywiście duża korelacja między liczbami reprezentującymi tę funkcję, więc dane powinny być dobrze kompresowane. Binarne dane zmiennoprzecinkowe zip / gzipping nie są jednak tak dobrze kompresowane. Zastanawiam się, czy istnieje metoda opracowana specjalnie do kompresji danych zmiennoprzecinkowych.

Wymagania:

  • Kompresja bezstratna lub możliwość określenia minimalnej liczby cyfr do zachowania (w niektórych aplikacjach doublemoże być więcej niż potrzebujemy, a floatmoże nie mieć wystarczającej precyzji).

  • Dobrze przetestowane narzędzie pracy (tj. Nie tylko artykuł opisujący metodę teoretyczną).

  • Nadaje się do kompresji danych liczbowych 1D (takich jak szeregi czasowe)

  • Wiele platform (musi działać w systemie Windows)

  • Musi być szybki --- najlepiej niewiele wolniejszy niż gzip. Odkryłem, że jeśli mam numery zapisane jako ASCII, gzipowanie pliku może przyspieszyć jego odczyt i przetwarzanie (ponieważ operacja może być związana z We / Wy).

Szczególnie chciałbym usłyszeć od ludzi, którzy faktycznie używali takiego narzędzia.

Szabolcs
źródło
Zostało to częściowo zainspirowane istnieniem FLAC , co sugeruje, że wyspecjalizowana metoda powinna (dużo?) Lepiej niż gzip.
Szabolcs
Patrzę na to teraz.
Szabolcs
Schludny. Dam temu wir.
meawoppl

Odpowiedzi:

22

Wypróbuj Blosc . W wielu przypadkach jest szybszy niż memcopy . Pomyśl o tym przez chwilę. . . niegodziwy.

Jest super stabilny, sprawdzony, ma wiele platform i działa jak mistrz.

meawoppl
źródło
och wow, to jest naprawdę fajne (i dla mnie nowe!)
Aron Ahmadia
Link jest zepsuty. Czy jest szansa, że ​​wiesz, gdzie jest teraz?
Alexis Wilke
1
@AlexisWilke Naprawiłem link. Był to pierwszy wynik wyszukiwania Google Blosc.
Doug Lipinski
1
Blosc jest może szybki, ale jego stopień kompresji na tablicach zmiennoprzecinkowych jest katastrofą. Dzięki najlepszej kompresji oferuje około 98% oryginalnego rozmiaru. W każdym razie dzięki za wskazówkę.
Kompresja tablic pływających zależy w dużej mierze od zawartości. Podejrzewam, że w bitach, które kompresujesz, jest mało (ustrukturyzowanych) informacji. Również blosc jest nadal aktywny przez 5 lat później!
meawoppl
7

Mam dobre wyniki przy użyciu HDF5 i jego filtra GZIP.

HDF5 zapewnia również filtr SZIP, który zapewnia lepsze wyniki dla niektórych zestawów danych naukowych.

Z mojego doświadczenia wynika, że ​​wybór kompresji zależy w dużej mierze od rodzaju danych, a analiza porównawcza jest prawdopodobnie jedynym sposobem na dokonanie dobrego wyboru.

BTW, filtry innych firm do HDF5 obejmują BLOSC, BZIP2, LZO, LZF, MAFISC.

f3lix
źródło
Dzięki za odpowiedź! Nie korzystałem dużo z HDF5. Czy to prawda, że ​​użycie filtra gzip w formacie HDF5 da mi taki sam współczynnik kompresji, jak zapisanie całej liczby do płaskiego pliku binarnego i uruchomienie go przez gzip? (Na razie zignoruj ​​możliwą wygodę / niedogodność korzystania z HDF5.) Jeśli chodzi o SZIP, czy jest on w jakiś sposób zoptymalizowany do zbiorów danych zmiennoprzecinkowych? (Jestem ciekawy i nie jest to jasne po przejrzeniu połączonej strony.) Strona mówi, że podstawową zaletą SZIP jest szybkość. GZIP jest również dość zgryźliwy (zwykle dekompresja gzip jest dla mnie znikoma).
Szabolcs
Skompresowany spakowany plik binarny będzie prawdopodobnie mniejszy niż plik HDF5 z filtrem gzip, ponieważ HDF5 to coś więcej niż surowe dane. Czasami przetwarzanie wstępne z filtrem losowym może poprawić wyniki gzip. Ale masz rację, zalety są raczej wygodą. Dzięki HDF5 łatwo jest zmienić filtr kompresji (wypróbować różne ustawienia), a HDF5 zapewnia funkcję dostępu do podzbiorów danych (przedziały w szeregach czasowych).
f3lix,
1
Jeśli wybierzesz tę trasę, sprawdź pyTables . To sprawia, że ​​powyższe to tylko kilka wierszy kodu. Utrzymywany (przynajmniej wcześniej) przez autora Blosc.
meawoppl
6

Prawdopodobnie można interpretować metody regresji lub transformacji (transformata Fouriera, transformata Chebysheva) jako „kompresję” danych szeregów czasowych lub funkcji 1D. Algorytm Remeza byłby kolejnym kandydatem. W takim przypadku użycie czegoś takiego jak regresja, FFT lub Czebyshev za pośrednictwem FFT byłoby przydatne do Twoich celów. To powiedziawszy, żadna z tych metod nie działa na danych szeregów czasowych o dowolnej strukturze. Na przykład w FFT zakłada się okresowość, a wszelkie nieciągłości w danych (lub brak okresowości) doprowadzą do zjawiska Gibbsa . Podobnie w przypadku transformacji Czebyszewa zakłada się, że dane opisują funkcję na .[1,1]

W zależności od funkcji podstawowej możesz być w stanie dopasować dane do postaci funkcjonalnej bez błędów, wymagając mniej współczynników do opisania formy funkcjonalnej niż masz punkt danych (co prowadzi do kompresji). W przypadku niektórych z tych metod istnieją wyniki błędów, chociaż nie wiem, czy którakolwiek z nich da ci ograniczenia a priori (lub a posteriori ) dotyczące błędu.

Możesz także przyjrzeć się metodom opracowanym specjalnie do kompresji liczb zmiennoprzecinkowych, takim jak FPC i powiązane algorytmy. Zobacz dokumenty tutaj , tutaj , tutaj , tutaj i tutaj , wraz ze stroną internetową zawierającą stary kod źródłowy tutaj .

Geoff Oxberry
źródło
Właściwie interesują mnie gotowe narzędzia podobne do gzip, które nie wymagają mojej pracy, szczególnie nie rozwijania i dostrajania własnej metody. Byłoby również korzystne, aby mieć metodę, która nie wymaga wczytywania całej rzeczy do pamięci przed jej dekompresją, ponieważ mogę mieć bardzo duże pliki danych, które można przetwarzać sekwencyjnie (działa to z gzip, ale nie, jeśli użyję Fouriera transformacja, chyba że sam podzielę dane na kawałki, co jeszcze bardziej skomplikuje całą sprawę). Coś, co zakłada, że ​​mój plik danych to tylko seria podwójnych danych binarnych, byłoby doskonałe.
Szabolcs,
Są to również transformacje 1: 1, a nie techniki kompresji. Można ich używać do tworzenia danych, na które naiwny algorytm kompresji może sobie poradzić, ale samodzielne rozwiązanie nie jest rozwiązaniem.
meawoppl
Niektóre z tych metod stanowią matematyczną podstawę algorytmów kompresji stosowanych w przetwarzaniu sygnałów, co było ideą stojącą za odpowiedzią. Te przekształcenia zwykle nie są 1: 1, z wyjątkiem szczególnych okoliczności.
Geoff Oxberry
3

HDF5 może wykorzystywać algorytm „tasowania”, w którym bajty dla N liczb zmiennoprzecinkowych są przestawiane w taki sposób, aby pierwsze bajty N liczb były pierwsze, a następnie drugie itd. Daje to lepsze współczynniki kompresji po zastosowaniu gzip, ponieważ jest bardziej prawdopodobne, że wytworzą dłuższe sekwencje o tej samej wartości. Zobacz tutaj kilka testów porównawczych .

xioxox
źródło
1

SZ (opracowany przez Argonne w 2016 roku) może być dobrym wyborem.

SZ: Szybki, zmiennoprzecinkowy kompresor danych o ograniczonym błędzie do zastosowań naukowych https://collab.cels.anl.gov/display/ESR/SZ

Linda
źródło
Jak myślisz, dlaczego może to być dobry wybór? Jakie są jego możliwości w porównaniu z innymi technikami kompresji?
Paweł
1

Możliwe metody, które można zastosować do kompresji zmiennoprzecinkowej:

  • Transpozycja 4xN dla liczb zmiennoprzecinkowych i 8xN dla liczb podwójnych + lz77
    Implementacja: Kompresja zmiennoprzecinkowa w TurboTranspose
    patrz także kompresja stratna ograniczona błędem

  • Predyktor (np. Metoda skończonego kontekstu) + kodowanie (np. „Kompresja liczb całkowitych”).
    Implementacja: Kompresja zmiennoprzecinkowa w TurboPFor, w
    tym specjalna kompresja dla szeregów czasowych.

  • jeśli to możliwe, przekonwertuj wszystkie liczby zmiennoprzecinkowe na liczby całkowite (np. 1.63 -> 163), a następnie użyj kompresji liczb całkowitych

  • Możesz przetestować wszystkie te metody na swoich danych za pomocą narzędzia icapp dla systemu Linux i Windows.

powturbo
źródło
1

Używamy ZFP z HDF5 do naszych danych obrazowania medycznego. Jest przeznaczony do stratnej, zmiennoprzecinkowej kompresji.

Działamy na dosłownie wszystkim i mamy ponad 40 TB danych przechowywanych (i używanych!). Jest wystarczająco szybki, aby zapisać nasze dane w czasie rzeczywistym, i możemy określić wymaganą precyzję, więc chociaż format jest stratny, nie widzimy żadnych różnic w końcowych wynikach.

LKlevin
źródło
0

Jeśli funkcja jest płynna, istnieje oczywiście duża korelacja między liczbami reprezentującymi tę funkcję, więc dane powinny być dobrze kompresowane.

Być może wymagany format wymaga przechowywania tylko przesunięć od wartości do wartości sąsiedniej.

Alternatywnie, być może mógłbyś wykorzystać domenę częstotliwości, być może nawet zapisując te wartości jako bezstratny plik audio, taki jak „bezstratny flac”, ponieważ potrzebujesz niektórych takich samych właściwości dźwięku.

Jednak zamierzam przyjąć inne podejście do próby odpowiedzi na pytanie, które, mam nadzieję, może być pomocne. Jak mówisz, to także, że minimalna długość opisu do przedstawienia tych danych jest mniejsza niż podanie wszystkich punktów danych.

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

Skutecznie program, kod komputerowy, jest dobrym przykładem. A jeśli nie przeszkadza ci, że coś, co jest przede wszystkim danymi działającymi przez wykonanie, a więc także kodem, możesz skompresować wartości zmiennoprzecinkowe do czegoś takiego jak funkcja lub formuła.

Wykonanie tego szczególnie dobrze automatycznie i przy realistycznych obliczeniach jest trudne. Jednak język Wolfram zapewnia pewne funkcje, aby spróbować:

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
źródło
0

Dlaczego nie zapisać po prostu float32 / float16? W numpy

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

Nie zrobi to, jeśli symulujesz efekt Motyla w teorii chaosu, ale są zrozumiałe, przenośne, „nie wymagają żadnej pracy z mojej strony”. A kompresja 2: 1/4: 1 ponad float64 jest trudna do pokonania :)

Uwagi:

„Typ tablicy float16 nie jest obsługiwany w np.linalg”; będziesz musiał go rozszerzyć do 32 lub 64 po wczytaniu.

Aby zobaczyć, jak różnią się parametry zmiennoprzecinkowe,

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

Aby zapoznać się z wykresem trywialnego przypadku testowego porównującego liczbę zmiennoprzecinkową 64 32 i 16, zobacz tutaj .

denis
źródło