2012-03-27 13 views
14

Estoy tratando de serializar una lista grande (~ 10 ** 6 filas, cada una con ~ 20 valores), para ser usada más tarde por mí mismo (así que la falta de seguridad de pickle no es una preocupación).Pickle alternatives

Cada fila de la lista es una tupla de valores, derivada de alguna base de datos SQL. Hasta ahora, he visto datetime.datetime, strings, integers y NoneType, pero es posible que tenga que admitir tipos de datos adicionales.

Para la serialización, he considerado pickle (cPickle), json y texto sin formato, pero solo pickle guarda la información del tipo: json no puede serializar datetime.datetime, y el texto sin formato tiene sus desventajas obvias.

Sin embargo, cPickle es bastante lento para datos tan grandes, y estoy buscando una alternativa más rápida.

¿Alguna sugerencia?

Gracias!

+1

¿Ha considerado eliminarlo en una base de datos SQLite? – rmmh

+0

En realidad, no lo he hecho. Podría ser el más simple ... –

Respuesta

4

Creo que deberías darle una mirada a PyTables. Debería ser ridículamente rápido, al menos más rápido que usar un RDBMS, ya que es muy laxo y no impone restricciones de lectura/escritura, además de que usted obtiene una mejor interfaz para administrar sus datos, al menos en comparación con la decapación.

+0

Parece prometedor. Lo intentaré, ¡gracias! –

1

Normalmente serializo en texto sin formato (* .csv) porque me pareció el más rápido. El módulo csv funciona bastante bien. Ver http://docs.python.org/library/csv.html

Si tiene que lidiar con Unicode para sus cadenas, consulte los ejemplos de UnicodeReader y UnicodeWriter al final.

Si serializas para tu propio uso futuro, supongo que sería suficiente saber que tienes el mismo tipo de datos por columna de csv (por ejemplo, la cadena siempre está en la columna 2).

+0

Eso no es tan bueno para mí, ya que no mantiene la información de tipo, tengo que recorrer los datos y convertirlos, lo cual es muy lento (al menos en mi implementación, usando una lista de comprensión de listas de comprensión). –

11

Pickle es en realidad bastante rápido siempre que no esté utilizando el protocolo (predeterminado) ASCII. Solo asegúrese de volcar usando protocol=pickle.HIGHEST_PROTOCOL.

+2

Cabe señalar que para 'python3' el formato predeterminado es en realidad binario, de acuerdo con los documentos. http://docs.python.org/3.4/library/pickle.html?highlight=pickle#pickle – Seanny123

+2

Una alternativa semánticamente mejor es 'protocol = pickle.HIGHEST_PROTOCOL' –

+1

Gracias, @moose! Actualizado desde 'protocol = -1'. –

4

búferes de protocolo son un mecanismo flexible, eficiente y automatizado para serializar datos estructurados - piensan XML, pero más pequeño, más rápido y más sencillo .

ventajas sobre XML:

  • son más simples
  • son de 3 a 10 veces más pequeño
  • son de 20 a 100 veces más rápido
  • son menos ambiguo
  • generar clases de acceso a datos que son más fáciles utilizar programáticamente

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

0

Durante cientos de miles de sencillo (hasta objetos complejidad de Python) compatible con JSON, he encontrado la mejor combinación de simplicidad, velocidad y tamaño mediante la combinación de:

late pickle y cPickle opciones por órdenes de magnitud.

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


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