Pickle dump énorme fichier sans erreur de mémoire
J'ai un programme où j'ai essentiellement ajuster la probabilité de certains événements basés sur ce qui est déjà connu. Mon fichier de données est déjà enregistré comme un cornichon Dictionnaire de l'objet à Dictionary.txt. Le problème, c'est qu'à chaque fois que je lance le programme, il tire dans le Dictionary.txt, le transforme en un objet dictionary, fait qu'il est modifie et remplace Dictionary.txt. C'est assez gourmande en mémoire que l'Dictionary.txt est de 123 MO. Quand je dump je suis le MemoryError, tout semble parfait quand je le tire..
- Est-il mieux (plus efficace) façon de faire les modifications? (Peut-être w/o avoir à remplacer la totalité du fichier à chaque fois)
- Est-il un moyen que je peux invoquer la collecte des ordures (par gc module)? (J'ai déjà l'auto-activé par gc.enable())
- Je sais qu'en plus de readlines (), vous pouvez lire ligne par ligne. Est-il un moyen de modifier le dictionnaire de manière incrémentielle, ligne par ligne, quand j'ai déjà bien rempli Dictionnaire de Fichier de l'objet dans le programme.
- D'autres solutions?
Je vous remercie pour votre temps.
Il y a un peu de résistance à la compression et à d'autres bibliothèques. Personnellement, j'aime l'aneth et H5Py pour les objets de grande taille. Si vous utilisez scikit apprendre et à utiliser un modèle de base sur le dictionnaire, peut-être que vous pourriez utiliser joblib (seulement vraiment pour ces modèles).
OriginalL'auteur user2543682 | 2013-07-07
Vous devez vous connecter pour publier un commentaire.
Je suis l'auteur d'un paquet appelé
klepto
(et également l'auteur dedill
).klepto
est construit pour stocker et récupérer des objets dans une manière très simple, et fournit une simple interface du dictionnaire de bases de données, la mémoire cache, et le stockage sur le disque. Ci-dessous, je montre stockage d'objets volumineux dans un "répertoire de l'archive", qui est un système de fichiers de répertoire avec un fichier par entrée. - Je choisir pour sérialiser les objets (c'est lent, mais il utilisedill
, de sorte que vous pouvez stocker presque n'importe quel objet), et je choisis un cache. À l'aide d'un cache mémoire me permet d'avoir un accès rapide au répertoire de l'archive, sans avoir à obtenir l'intégralité de l'archive dans la mémoire. L'interaction avec une base de données ou le fichier peut être lent, mais l'interaction avec la mémoire est rapide... et vous pouvez remplir la mémoire cache que vous le souhaitez à partir de l'archive.klepto
fournit rapide et flexible l'accès à de grandes quantités d'espace de stockage, et si l'archive permet en parallèle d'accès (par exemple, certaines bases de données), alors vous pouvez lire les résultats en parallèle. Il est également facile de partager les résultats dans les différents processus parallèles ou sur des machines différentes. Ici, j'ai créer un deuxième archive instance, a souligné le même répertoire de l'archive. Il est facile de passer les clés entre les deux objets, et fonctionne de la même façon à partir d'un autre processus.Vous pouvez aussi choisir parmi différents niveaux de compression de fichiers, et si
vous voulez que les fichiers soient mappés en mémoire. Il ya beaucoup de différents
options, à la fois pour les fichiers backend et pilotes de base de données. L'interface
est identique, cependant.
Par rapport à vos autres questions au sujet de la collecte des ordures et la modification de certaines parties du dictionnaire, les deux sont possibles avec
klepto
, que vous pouvez charger et supprimer des objets de la mémoire cache, de vidage, de charge et de synchronisation avec l'archive backend, ou de tout autre dictionnaire de méthodes.Voir plus de tutoriel ici: https://github.com/mmckerns/tlkklp
Obtenir
klepto
ici: https://github.com/uqfoundationd.dump(); d.clear(); gc.collect()
entre chaque affectation d'un tableau numpy pourd
. Ce n'assure qu'un tableau numpy est en mémoire à la fois, utile si les tableaux sont juste assez grand pour tenir en mémoire (comme le mien).Qu'advient-il si vous avez un dictionnaire qui vous souhaitez enregistrer sur le disque? Par exemple, si je effectuer
for key in mydict: d[key] = mydict[key]
, serait-il copier les données ou garder une référence?Si vous disposez déjà d'une dict, vous pouvez passer à un nouveau
klepto
archive avec ledict
mot-clé. Je crois qu'il ne faut pas faire une copie.avez-vous l'esprit en ajoutant un exemple de code à votre réponse? Je crois qu'il serait bénéfique pour les futurs lecteurs.
il suffit de remplacer le
{}
avec un non-vide dict dans le code ci-dessus. Cela devrait le faire.OriginalL'auteur Mike McKerns
J'ai eu le même problème. J'utilise joblib et le travail a été fait. Dans le cas où si quelqu'un veut connaître d'autres possibilités.
enregistrer le modèle à disque
quelques temps plus tard... charge le modèle de disque
OriginalL'auteur Ch HaXam
Si vos clés et des valeurs de chaîne, vous pouvez utiliser l'une de l'embedded persistante clé-valeur moteurs de stockage disponible en Python à la bibliothèque standard. Exemple de la
anydbm
module docs:anydbm
dessous pour stocker arbitraire pickleable objets de valeurs (les clés sont toujours des chaînes de caractères). Ainsi, le décapage et la unpickling qui se passe au niveau de la granularité de valeurs. Par défaut, une étagère persiste valeurs sur le disque à chaque fois que nous assignons à l'une de ses touches.OriginalL'auteur Imran
Avez-vous essayé d'utiliser streaming cornichon: https://code.google.com/p/streaming-pickle/
Je viens de résoudre une semblable erreur de mémoire par le passage à la diffusion de cornichon.
OriginalL'auteur Chris Wheadon
J'ai eu une erreur de la mémoire et résolu en utilisant le protocole=2:
cPickle.dump(obj, file, protocol=2)
OriginalL'auteur denfromufa
Comment à ce sujet?
se pourrait-il que le fichier objet n'est jamais fermé?
OriginalL'auteur richie
J'ai récemment eu ce problème. Après avoir essayé cpickle avec l'ASCII et le protocole binaire 2, j'ai trouvé que ma SVM auprès de la sci-kit d'apprendre formés sur+ de 20 go de données n'a pas été le décapage due à une erreur de mémoire. Cependant, l'aneth paquet semble résoudre le problème. L'aneth ne va pas créer de nombreuses améliorations pour un dictionnaire, mais il peut aider avec le streaming. Il est destiné à flux marinés octets à travers un réseau.
Si l'efficacité est un problème, essayez de chargement/sauvegarde d'une base de données. Dans ce cas, votre solution de stockage peut être un problème. 123 mo Pandas doit être fine. Toutefois, si la machine est limitée de mémoire de SQL offre rapide,optimisé, sac opérations sur les données, généralement avec multithread de soutien.
Mon poly noyau svm enregistré.
OriginalL'auteur Andrew Scott Evans
Aucune des réponses ci-dessus, a travaillé pour moi. J'ai fini par utiliser Hickle une baisse-dans le remplacement pour pickle basé sur HDF5. Au lieu de l'enregistrer à un cornichon c'est l'enregistrement de données dans HDF5 fichier. L'API est identique pour la plupart des cas d'utilisation et il a quelques fonctionnalités vraiment cool, comme la compression.
Exemple:
klepto
peut également vidage à HDF5, semblable àhickle
et python 3.x compatible.OriginalL'auteur gidim
Cela peut sembler trivial, mais essayez d'utiliser le 64 bits Python si vous n'êtes pas.
OriginalL'auteur lyron