Obecnie CSV
za każdym razem, gdy uruchamiam skrypt, importuję dość dużą ramkę danych. Czy istnieje dobre rozwiązanie, aby utrzymywać tę ramkę danych stale dostępną między uruchomieniami, aby nie musiałem spędzać całego czasu na czekaniu na uruchomienie skryptu?
317
Odpowiedzi:
Najprostszym sposobem jest marynowanie go za pomocą
to_pickle
:Następnie możesz go ponownie załadować, używając:
Uwaga: przed 0.11.1
save
iload
były jedynym sposobem na to (teraz są one przestarzałe na korzyśćto_pickle
iread_pickle
odpowiednio).Innym popularnym wyborem jest użycie HDF5 ( pytania ), który oferuje bardzo szybki czas dostępu dla dużych zestawów danych:
Bardziej zaawansowane strategie są omówione w książce kucharskiej .
Od wersji 0.13 istnieje również msgpack, który może być lepszy dla interoperacyjności, jako szybsza alternatywa dla JSON, lub jeśli masz dane obiektów / tekstochłonne dla Pythona (zobacz to pytanie ).
źródło
Chociaż są już pewne odpowiedzi, znalazłem ładne porównanie, w którym próbowali szeregować serializacje Pandas DataFrames: Skutecznie przechowuj Pandas DataFrames .
Porównują:
W swoim eksperymencie serializują ramkę danych o wartości 1 000 000 wierszy, a dwie kolumny testowane są osobno: jedna z danymi tekstowymi, druga z liczbami. Ich zastrzeżenie mówi:
Kod źródłowy testu, do którego się odnoszą, jest dostępny online . Ponieważ ten kod nie działał bezpośrednio, wprowadziłem kilka drobnych zmian, które można uzyskać tutaj: serialize.py Otrzymałem następujące wyniki:
Wspominają również, że przy konwersji danych tekstowych na dane kategoryczne serializacja jest znacznie szybsza. W ich teście około 10 razy szybciej (zobacz także kod testowy).
Edycja : Wyższy czas marynowania niż CSV można wytłumaczyć zastosowanym formatem danych. Domyślnie
pickle
używa drukowanej reprezentacji ASCII, która generuje większe zestawy danych. Jak widać z wykresu, piklowanie przy użyciu nowszego formatu danych binarnych (wersja 2pickle-p2
) ma znacznie krótsze czasy ładowania.Inne odniesienia:
numpy.fromfile
jest najszybszy.źródło
.to_pickle()
(który używa pamięci binarnej) z.to_hdf()
(bez kompresji). Celem była szybkość, rozmiar pliku dla HDF 11x Pickle i czas do załadowania było 5x Pickle. Moje dane to ~ 5k plików ~ 7k wierszy x 6 kols każdy, głównie numerycznych.Jeśli dobrze rozumiem, już używasz,
pandas.read_csv()
ale chcesz przyspieszyć proces programowania, abyś nie musiał ładować pliku za każdym razem, gdy edytujesz skrypt, prawda? Mam kilka rekomendacji:możesz załadować tylko część pliku CSV, używając
pandas.read_csv(..., nrows=1000)
tylko do załadowania górnego bitu tabeli podczas tworzeniaużyj ipython do interaktywnej sesji, tak aby zachować tabelę pand w pamięci podczas edycji i ponownego ładowania skryptu.
przekonwertować plik csv na tabelę HDF5
zaktualizowane użycie
DataFrame.to_feather()
ipd.read_feather()
do przechowywania danych w formacie binarnym piórkowym kompatybilnym z R, który jest super szybki (w moich rękach, nieco szybszy niżpandas.to_pickle()
w przypadku danych liczbowych i znacznie szybszy w przypadku danych ciągowych).Możesz być także zainteresowany tą odpowiedzią na stackoverflow.
źródło
to_feather
miałby dobrze działać na danych ciągów? Przeprowadziłem testyto_pickle
ito_feature
na mojej numerycznej ramce danych i pikle jest około 3 razy szybsza.Marynata działa dobrze!
źródło
.pkl
zgodnie z sugestią @Andy Haydens.Możesz użyć pliku w formacie piórkowym. To jest bardzo szybkie.
źródło
R
pomocąfeather
biblioteki.Pandas DataFrames mają
to_pickle
funkcję przydatną do zapisywania DataFrame:źródło
Jak już wspomniano, istnieją różne opcje i formaty plików ( HDF5 , JSON , CSV , parkiet , SQL ) do przechowywania ramki danych. Jednak
pickle
nie jest obywatelem pierwszej klasy (w zależności od konfiguracji), ponieważ:pickle
jest potencjalnym zagrożeniem bezpieczeństwa. Utwórz dokumentację Pythona dla marynaty :pickle
jest wolny. Znajdź tutaj i tutaj testy porównawcze.W zależności od konfiguracji / użytkowania oba ograniczenia nie mają zastosowania, ale nie zalecałbym
pickle
jako domyślnej trwałości ramek danych pand.źródło
Formaty plików Numpy są dość szybkie w przypadku danych liczbowych
Wolę używać plików numpy, ponieważ są one szybkie i łatwe w obsłudze. Oto prosty test porównawczy do zapisywania i ładowania ramki danych z 1 kolumną 1 miliona punktów.
za pomocą
%%timeit
magicznej funkcji ipythonwyjście jest
aby załadować dane z powrotem do ramki danych
wyjście jest
NIE JEST ZŁY!
CONS
Występuje problem, jeśli zapiszesz plik numpy za pomocą Pythona 2, a następnie spróbujesz otworzyć go za pomocą Pythona 3 (lub odwrotnie).
źródło
https://docs.python.org/3/library/pickle.html
Formaty protokołu piklowania:
Wersja protokołu 0 jest oryginalnym protokołem „czytelnym dla człowieka” i jest wstecznie kompatybilna z wcześniejszymi wersjami Pythona.
Wersja protokołu 1 jest starym formatem binarnym, który jest również zgodny z wcześniejszymi wersjami Pythona.
Wersja protokołu 2 została wprowadzona w Pythonie 2.3. Zapewnia znacznie bardziej wydajne wytrawianie klas w nowym stylu. Informacje na temat ulepszeń wprowadzonych przez protokół 2 znajdują się w PEP 307.
Protokół w wersji 3 został dodany w Pythonie 3.0. Ma jawną obsługę obiektów bajtów i nie może zostać usunięty przez Python 2.x. Jest to domyślny protokół i zalecany protokół, gdy wymagana jest kompatybilność z innymi wersjami Python 3.
Wersja protokołu 4 została dodana w Pythonie 3.4. Dodaje obsługę bardzo dużych obiektów, wytrawianie większej liczby rodzajów obiektów i niektóre optymalizacje formatu danych. Informacje na temat ulepszeń wprowadzonych przez protokół 4 można znaleźć w PEP 3154.
źródło
kompatybilność z wróblem między wersjami
Ogólny ruch został skierowany do pióra / pióra (ostrzeżenia o wycofaniu z pand / msgpack). Mam jednak wyzwanie w przypadku kruszywa z przejściową specyfikacją Dane zserializowane w kruszywie 0.15.1 nie mogą być deserializowane za pomocą 0.16.0 ARROW-7961 . Używam serializacji, aby użyć redis, więc muszę użyć kodowania binarnego.
Przetestowałem różne opcje (za pomocą notatnika Jupyter)
Z następującymi wynikami dla mojej ramki danych (w
out
zmiennej jupyter)pióro i parkiet nie działają w mojej ramce danych. Będę nadal używać pyarrowa. Jednak uzupełnię marynatą (bez kompresji). Pisząc do pamięci podręcznej, przechowuj puchary i marynowane zserializowane formy. Podczas odczytywania z rezerwowej pamięci podręcznej do piklowania, jeśli desekrializacja kruszyny nie powiedzie się.
źródło
Format zależy od przypadku użycia
Porównanie formatów plików pand znajduje się w tym filmie .
źródło