Est-il une mémoire efficace et rapide pour charger de gros fichiers json en python?
J'ai quelques fichiers json avec 500 MO.
Si j'utilise le "trivial" json.charger pour charger son contenu tout à la fois, il va consommer beaucoup de mémoire.
Est-il un moyen de lire partiellement le fichier? Si c'était un texte, d'un fichier délimité, je serais en mesure de parcourir les lignes. Je suis à la recherche d'analogie à elle.
Des suggestions?
Grâce
- Le problème, je suis confronté est que j'ai 195 fichiers tels que, pour que et il semble que python garbage collector n'est pas de faire un bon travail. Après le 10ème fichier, je n'ai plus de mémoire. Je suis à l'aide de Python 2.6.4 sur windows 7. J'ai 3 GO de mémoire ram
- Pourquoi avez-vous besoin de tous les charger dans la mémoire à la fois? Qui semble inefficace.
- Je n'ai pas à tous les charger à la fois, mais il semble que le garbage collector ne fonctionne pas bien. Il consomme un lor de mémoire après de nombreux fichiers sont fermés. Quand je itérer sur tous les fichiers, l'objet json a toujours le même nom de variable et je suppose que le garbage collector devrait libérer de la mémoire que les autres fichiers occupé. Mais cela n'a tout simplement pas happeb
- que le garbage collector devrait libérer de la mémoire", Il devrait. Comme il n'a pas, autre chose est erroné.
- Montre-nous ton code!
- est-il judicieux?
- La réponse par @Jim Pivarski doit être accepté par un.
- stackoverflow.com/questions/10382253/...
Vous devez vous connecter pour publier un commentaire.
Réponse courte: non.
Correctement la division d'un fichier json en prendrait connaissance intime de l'objet json graphique pour obtenir le droit.
Toutefois, si vous avez cette connaissance, alors vous pourriez mettre en œuvre un fichier-comme l'objet qui encapsule le fichier json et crache bon morceaux.
Par exemple, si vous savez que votre fichier json est un tableau d'objets, vous pouvez créer un générateur qui enveloppe le fichier json et retourne les morceaux de la matrice.
Vous devez faire une chaîne de contenu analyse pour obtenir la segmentation du fichier json droit.
Je ne sais pas ce que génère votre contenu json. Si possible, je voudrais envisager de générer un nombre gérable de fichiers, au lieu d'un énorme fichier.
Il y avait un double à cette question, qui a eu une meilleure réponse. Voir https://stackoverflow.com/a/10382359/1623645, ce qui suggère ijson.
Mise à jour:
Je l'ai essayé, et ijson est en JSON ce SAX est au format XML. Par exemple, vous pouvez faire ceci:
où
prefix
est séparé par des points d'indice dans le JSON de l'arbre (ce qui se produit si le nom de vos clés ont des points en eux? Je suppose que ce serait mauvais pour Javascript, trop...),theType
décrit un SAX-comme événement, l'un des'null', 'boolean', 'number', 'string', 'map_key', 'start_map', 'end_map', 'start_array', 'end_array'
, etvalue
est la valeur de l'objet ou deNone
sithe_type
est un événement de début/fin d'une carte/tableau.Le projet a certains docstrings, mais pas assez de documentation mondiale. J'ai dû creuser dans
ijson/common.py
à trouver ce que je cherchais.Donc, le problème n'est pas que chaque fichier est trop gros, mais qu'il y a trop d'entre eux, et ils semblent être en ajoutant de la mémoire. Python garbage collector devrait être bon, sauf si vous êtes en gardant autour de références que vous n'avez pas besoin. Il est difficile de dire exactement ce qui se passe, sans aucune autre information, mais certaines des choses que vous pouvez essayer:
Modulariser le code. Faire quelque chose comme:
Si vous écrivez
process_file()
de telle manière qu'il ne repose pas sur du tout de l'état global, et ne paschangement à l'échelle mondiale de l'état, le garbage collector devrait être en mesure de faire son travail.
Traiter chaque fichier dans un processus séparé. Au lieu d'analyser tous les fichiers JSON à la fois, écrire un
programme qui analyse un seul, et de passer de l'un à partir d'un script shell, ou à partir d'un autre python
processus qui appelle votre script via
subprocess.Popen
. C'est un peu moins élégante, mais sirien d'autre ne fonctionne, il fera en sorte que vous n'êtes pas tenue sur des données périmées, d'un fichier à l'
prochaine.
Espère que cette aide.
Oui.
Vous pouvez utiliser jsonstreamer SAX-comme push analyseur que j'ai écrit qui vont vous permettre d'analyser arbitraire de la taille des morceaux, vous pouvez obtenez-le ici et extraire le fichier lisez-moi pour des exemples. Son rapide car il utilise le 'C' yajl bibliothèque.
Sur votre mention de manquer de mémoire, je dois remettre en question si vous êtes en train de gestion de la mémoire. Êtes-vous à l'aide de la "del" mot-clé à supprimer votre ancien objet avant d'essayer de lire un nouveau? Python ne doit jamais silencieusement conserver quelque chose dans la mémoire si vous le retirez.
"le garbage collector devrait libérer de la mémoire"
Correcte.
Puisqu'il n'en a pas, autre chose est erroné. Généralement, le problème avec l'infini de la mémoire de croissance des variables globales.
Supprimer toutes les variables globales.
Faire tous les code au niveau du module en petites fonctions.
Une autre idée est d'essayer de le charger dans un document base de données de banque comme MongoDB.
Il traite avec de grosses gouttes de JSON bien. Bien que vous pouvez exécuter dans le même problème de chargement de l'JSON - éviter le problème en chargeant les fichiers un à un.
Si le chemin d'accès qui fonctionne pour vous, alors vous pouvez interagir avec les données JSON via leur client et, potentiellement, de ne pas avoir à tenir l'ensemble du blob dans la mémoire
http://www.mongodb.org/
en plus de @codeape
Je voudrais essayer d'écrire un parser json personnalisé pour vous aider à comprendre la structure du JSON blob qui vous avez affaire. Imprimer les noms de clé seulement, etc. Faire un arbre hiérarchique et de décider (vous-même) comment vous pouvez morceau il. De cette façon, vous pouvez faire ce que @codeape suggère, de diviser le fichier en petits morceaux, etc