2012-03-27 18 views
14

Próbuję serializować duże (~ 10 ** 6 wierszy, każde z ~ 20 wartościami) listy, które będą używane później przeze mnie (więc brak bezpieczeństwa dla marynarzy nie jest problemem).Alternatywy dla marynowania

Każdy wiersz listy jest krotką wartości pochodzących z pewnej bazy danych SQL. Do tej pory widziałem datetime.datetime, ciągi, liczby całkowite i NoneType, ale może ewentualnie musiałem obsługiwać dodatkowe typy danych.

Do serializacji rozważałem marynowanie (cPickle), json i zwykły tekst - ale tylko pikle zapisuje informacje o typie: json nie może serializować datetime.datetime, a zwykły tekst ma swoje oczywiste wady.

Jednak cPickle jest dość wolny w przypadku tak dużych danych i szukam szybszej alternatywy.

Wszelkie sugestie?

Dzięki!

+1

Czy rozważałeś wyrzucenie go do bazy danych SQLite? – rmmh

+0

Właściwie - nie mam. Może być najprostszy ... –

Odpowiedz

4

Myślę, że powinieneś dać PyTables spojrzenie. To powinno być śmiesznie szybkie, przynajmniej szybsze niż używanie RDBMS, ponieważ jest bardzo luźne i nie nakłada żadnych ograniczeń odczytu/zapisu, a także dostaje lepszy interfejs do zarządzania swoimi danymi, przynajmniej w porównaniu do ich marynowania.

+0

Wygląda obiecująco. Dam ci szansę - dzięki! –

1

Zwykle serializuje się do zwykłego tekstu (* .csv), ponieważ znalazłem go najszybciej. Moduł csv działa bardzo dobrze. Zobacz http://docs.python.org/library/csv.html

Jeśli masz do czynienia z unikodem dla swoich ciągów, sprawdź przykłady UnicodeReader i UnicodeWriter na końcu.

Jeśli serializuje się do własnego użytku w przyszłości, wydaje mi się, że wystarczy wiedzieć, że w kolumnie csv jest taki sam typ danych (np. Ciąg zawsze znajduje się w kolumnie 2).

+0

To nie jest dobre dla mnie - ponieważ nie zachowuje informacji o typie, muszę zapętlić dane i przekonwertować je, co jest bardzo powolne (przynajmniej w mojej implementacji, używając listowego zrozumienia ze zrozumieniem listy). –

11

Pickle jest rzeczywiście dość szybki, o ile nie używasz (domyślnie) protokołu ASCII. Po prostu upewnij się, że zrzutu używasz protocol=pickle.HIGHEST_PROTOCOL.

+2

Należy zauważyć, że dla 'python3' domyślny format jest faktycznie binarny, zgodnie z dokumentami. http://docs.python.org/3.4/library/pickle.html?highlight=pickle#pickle – Seanny123

+2

Semantycznie lepszą alternatywą jest 'protocol = pickle.HIGHEST_PROTOCOL' –

+1

Dzięki, @moose! Zaktualizowano z 'protocol = -1'. –

0

Dla setek tysięcy proste (do JSON-compatible) złożoność obiektów Pythona, znalazłem najlepsze połączenie prostoty, szybkości i wielkości łącząc:

Bije pickle i cPickle opcje o rzędy wielkości.

with gzip.open(filename, 'wb') as f: 
    ubjson.dump(items, f) 


with gzip.open(filename, 'rb') as f: 
    return ubjson.load(f)