guardar - ¿Existe una manera eficiente y rápida de cargar archivos grandes JSON en python?
python json to dict (8)
"el recolector de basura debería liberar la memoria"
Correcto.
Como no es así, algo más está mal. En general, el problema con el crecimiento de la memoria infinita son las variables globales.
Eliminar todas las variables globales.
Convierta todos los códigos de nivel de módulo en funciones más pequeñas.
Tengo algunos archivos json con 500MB. Si utilizo el json.load "trivial" para cargar su contenido todo de una vez, consumirá mucha memoria.
¿Hay alguna manera de leer parcialmente el archivo? Si fuera un archivo de texto delimitado por líneas, podría iterar sobre las líneas. Estoy buscando una analogía para eso.
¿Alguna sugerencia? Gracias
Cuando menciona que se está quedando sin memoria, debo preguntar si realmente está administrando la memoria. ¿Estás usando la palabra clave "del" para eliminar tu objeto anterior antes de intentar leer uno nuevo? Python nunca debe retener silenciosamente algo en la memoria si lo elimina.
Entonces, el problema no es que cada archivo sea demasiado grande, sino que hay demasiados y parece que se están acumulando en la memoria. El recolector de basura de Python debería estar bien, a menos que guardes las referencias que no necesitas. Es difícil saber exactamente qué está sucediendo sin más información, pero hay algunas cosas que puedes probar:
Modula tu código Haz algo como:
for json_file in list_of_files: process_file(json_file)
Si escribe
process_file()
de tal manera que no dependa de ningún estado global y no cambie ningún estado global, el recolector de basura debería poder hacer su trabajo.Trate con cada archivo en un proceso separado. En lugar de analizar todos los archivos JSON a la vez, escriba un programa que analice solo uno, y pase cada uno desde un script de shell, o desde otro proceso de python que llame a su script a través del
subprocess.Popen
. Esto es un poco menos elegante, pero si nada funciona, se asegurará de que no estés reteniendo los datos obsoletos de un archivo al siguiente.
Espero que esto ayude.
Hubo un duplicado de esta pregunta que tenía una mejor respuesta. Ver https://.com/a/10382359/1623645 , que sugiere ijson .
Actualizar:
Lo probé, e ijson es para JSON lo que SAX es para XML. Por ejemplo, puedes hacer esto:
import ijson
for prefix, the_type, value in ijson.parse(open(json_file_name)):
print prefix, the_type, value
donde el prefix
es un índice separado por puntos en el árbol JSON (¿qué sucede si los nombres de las teclas tienen puntos en ellos? Supongo que también sería malo para Javascript ...), theType
describe un evento tipo SAX, uno de ''null'', ''boolean'', ''number'', ''string'', ''map_key'', ''start_map'', ''end_map'', ''start_array'', ''end_array''
, y value
es el valor del objeto o None
si the_type
es un evento como iniciar / terminar un mapa / matriz.
El proyecto tiene algunas cadenas de documentación, pero no suficiente documentación global. Tuve que buscar en ijson/common.py
para encontrar lo que estaba buscando.
Otra idea es intentar cargarla en una base de datos de almacenamiento de documentos como MongoDB. Se trata de grandes manchas de JSON también. Aunque podría encontrarse con el mismo problema al cargar JSON, evite el problema cargando los archivos de uno en uno.
Si la ruta de acceso funciona para usted, entonces puede interactuar con los datos de JSON a través de su cliente y posiblemente no tenga que mantener todo el blob en la memoria
Respuesta corta: no.
La división correcta de un archivo json requeriría un conocimiento íntimo del gráfico del objeto json para hacerlo bien.
Sin embargo, si tiene este conocimiento, puede implementar un objeto similar a un archivo que envuelva el archivo json y escuche los fragmentos adecuados.
Por ejemplo, si sabe que su archivo json es una única matriz de objetos, puede crear un generador que envuelva el archivo json y devuelva fragmentos de la matriz.
Tendría que hacer un análisis sintáctico del contenido de la cadena para obtener la fragmentación correcta del archivo json.
No sé qué genera tu contenido json. Si es posible, consideraría generar una cantidad de archivos manejables, en lugar de un solo archivo enorme.
Sí.
Puede usar el analizador de impulsos jsonstreamer SAX que he escrito, que le permitirá analizar fragmentos de tamaño arbitrario, puede obtenerlo aquí y consultar el archivo README para ver ejemplos. Es rápido porque usa la biblioteca ''C'' yajl.
además de @codeape
Intentaría escribir un analizador json personalizado para ayudarlo a descubrir la estructura del blob JSON con el que está tratando. Imprima solo los nombres de las teclas, etc. Haga un árbol jerárquico y decida (usted mismo) cómo puede dividirlo. De esta forma, puede hacer lo que @codeape sugiere: dividir el archivo en trozos más pequeños, etc.