2012-01-05 27 views
5

He generado por pickle.dump() un archivo con el tamaño de unos 5 GB. Lleva aproximadamente medio día cargar este archivo y aproximadamente 50GM de RAM. Mi pregunta es si es posible leer este archivo accediendo por separado, entrada por entrada (uno a la vez) en lugar de cargarlo todo en la memoria, o si tiene alguna otra sugerencia de cómo acceder a los datos en dicho archivo.Cargando un gran diccionario de Python Pickle

Muchas gracias.

+4

¿Qué le parece una base de datos? http://docs.python.org/library/sqlite3.html – FogleBird

+0

5 GB wow, ¿puedo preguntar qué estás intentando eliminar usando Pickle? – mouad

+1

¿qué tipo de datos tienes? Estoy pensando en un [hdf5] (http://www.hdfgroup.org/HDF5/) archivo de datos – konus

Respuesta

7

No hay duda de que esto se debe hacer usando una base de datos, en lugar de pickle, las bases de datos están diseñadas exactamente para este tipo de problema.

Aquí hay un código para comenzar, que coloca un diccionario en una base de datos sqllite y muestra un ejemplo de cómo recuperar un valor. Para que esto funcione con tu diccionario real en lugar de mi ejemplo de juguete, necesitarás aprender más sobre SQL, pero afortunadamente hay muchos recursos excelentes disponibles en línea. En particular, es posible que desee aprender a usar SQLAlchemy, que es un "Asignador relacional de objetos" que puede hacer que trabajar con bases de datos sea tan intuitivo como trabajar con objetos.

import os 
import sqlite3 

# an enormous dictionary too big to be stored in pickle 
my_huge_dictionary = {"A": 1, "B": 2, "C": 3, "D": 4} 

# create a database in the file my.db 
conn = sqlite3.connect('my.db') 
c = conn.cursor() 

# Create table with two columns: k and v (for key and value). Here your key 
# is assumed to be a string of length 10 or less, and your value is assumed 
# to be an integer. I'm sure this is NOT the structure of your dictionary; 
# you'll have to read into SQL data types 
c.execute(""" 
create table dictionary (
k char[10] NOT NULL, 
v integer NOT NULL, 
PRIMARY KEY (k)) 
""") 

# dump your enormous dictionary into a database. This will take a while for 
# your large dictionary, but you should do it only once, and then in the future 
# make changes to your database rather than to a pickled file. 
for k, v in my_huge_dictionary.items(): 
    c.execute("insert into dictionary VALUES ('%s', %d)" % (k, v)) 

# retrieve a value from the database 
my_key = "A" 
c.execute("select v from dictionary where k == '%s'" % my_key) 
my_value = c.next()[0] 
print my_value 

¡Buena suerte!

+0

Muchas gracias David, ¡eso realmente ayuda! – user1132834

+0

O simplemente use [sqlitedict] (https://pypi.python.org/pypi/sqlitedict), para preservar la cordura. – Radim

0

Puede probar una base de datos orientada a objetos, si sus datos son heterogéneos -utilizando ZODB -que utiliza internamente pickle, pero de una manera diseñada y probada- para administrar grandes cantidades de datos, probablemente necesitará pocos cambios en su aplicación

ZODB es el corazón de Zope, un servidor de aplicaciones Python, que hoy impulsa a Plone, entre otras aplicaciones.

Se puede usar de manera independiente, sin todas las herramientas de Zope, debería verificarlo, doblemente si sus datos no son aptos para SQL.

http://www.zodb.org/

Cuestiones relacionadas