2012-03-27 16 views
14

Sto provando a serializzare un elenco di grandi dimensioni (~ 10 ** 6 righe, ognuna con ~ 20 valori), da utilizzare in seguito da solo (quindi la mancanza di sicurezza di Pickle non è un problema).Alternative sottaceto

Ogni riga dell'elenco è una tupla di valori, derivata da alcuni database SQL. Finora, ho visto datetime.datetime, stringhe, interi e NoneType, ma alla fine potrei dover supportare tipi di dati aggiuntivi.

per la serializzazione, ho considerato salamoia (cPickle), JSON, e testo in chiaro - ma solo salamoia salva le informazioni sul tipo: JSON non può serializzare datetime.datetime, e solo testo ha i suoi svantaggi evidenti.

Tuttavia, cPickle è piuttosto lento per i dati così grandi e sto cercando un'alternativa più veloce.

Qualche suggerimento?

Grazie!

+1

Avete considerato di scaricarlo in un database SQLite? – rmmh

+0

In realtà - Non ho. Potrebbe essere il più semplice ... –

risposta

4

Penso che dovresti dare un'occhiata a PyTables. Dovrebbe essere incredibilmente veloce, almeno più veloce dell'utilizzo di un RDBMS, poiché è molto lassista e non impone alcuna restrizione in lettura/scrittura, oltre a ottenere un'interfaccia migliore per la gestione dei dati, almeno rispetto al decapaggio.

+0

Sembra promettente. Darò un colpo - grazie! –

1

Generalmente serializzo in testo normale (* .csv) perché ho trovato che fosse il più veloce. Il modulo csv funziona abbastanza bene. Vedi http://docs.python.org/library/csv.html

Se si ha a che fare con unicode per le stringhe, controllare gli esempi UnicodeReader e UnicodeWriter alla fine.

Se si serializzare per uso proprio futuro, credo che sarebbe sufficiente sapere che si ha lo stesso tipo di dati per colonna csv (ad esempio, stringa sempre sulla colonna 2).

+0

Questo non è così buono per me - in quanto non mantiene le informazioni di tipo, devo ciclo sui dati e convertirlo, che è molto lento (almeno nella mia implementazione base ad una lista di comprensione di list comprehension). –

11

Pickle è in realtà abbastanza veloce fino a quando non si utilizza il protocollo ASCII (predefinito). Assicurati di scaricare usando protocol=pickle.HIGHEST_PROTOCOL.

+2

Va notato che per 'python3' il formato predefinito è in realtà binario, secondo i documenti. http://docs.python.org/3.4/library/pickle.html?highlight=pickle#pickle – Seanny123

+2

Un semanticamente migliore alternativa è 'protocollo = pickle.HIGHEST_PROTOCOL' –

+1

Grazie, @moose! Aggiornato da 'protocollo = -1'. –

4

buffer di protocollo sono una, efficiente, il meccanismo automatico flessibile per la serializzazione dei dati strutturati - pensano XML, ma più piccolo, più veloce e più semplice .

vantaggi rispetto XML:

  • sono più semplici
  • sono da 3 a 10 volte più piccolo
  • sono da 20 a 100 volte più veloce
  • sono meno ambiguo
  • generare classi di accesso ai dati che sono più facili utilizzare a livello di programmazione

https://developers.google.com/protocol-buffers/docs/pythontutorial

0

Per centinaia di migliaia di semplici (fino a JSON-compatibile) oggetti complessità Python, ho trovato la migliore combinazione di semplicità, velocità e dimensioni combinando:

Batte pickle e cPickle opzioni di ordini di grandezza.

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


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