J'ai un très gros fichier csv que j'ai ouvert dans les pandas comme suit ...
import pandas
df = pandas.read_csv('large_txt_file.txt')
Une fois que je fais cela, mon utilisation de la mémoire augmente de 2 Go, ce qui est attendu car ce fichier contient des millions de lignes. Mon problème survient lorsque j'ai besoin de libérer cette mémoire. L'Iran....
del df
Cependant, mon utilisation de la mémoire n'a pas baissé. Est-ce la mauvaise approche pour libérer la mémoire utilisée par une trame de données pandas? Si c'est le cas, quelle est la bonne manière?
gc
module et appelergc.collect()
mais il peut ne pas récupérer la mémoiredel df
n'est pas appelé directement après la création de df droit? Je pense qu'il y a des références au df au moment où vous supprimez le df. Donc, il ne sera pas supprimé au lieu de cela, il supprime le nom.df = ''
à la fin de votre code? Semble effacer la RAM utilisée par la trame de données.Réponses:
Réduire l'utilisation de la mémoire en Python est difficile, car Python ne libère pas réellement de mémoire vers le système d'exploitation . Si vous supprimez des objets, alors la mémoire est disponible pour les nouveaux objets Python, mais pas
free()
pour revenir au système ( voir cette question ).Si vous vous en tenez aux tableaux numpy numériques, ceux-ci sont libérés, mais les objets encadrés ne le sont pas.
Réduction du nombre de Dataframes
Python garde notre mémoire à un filigrane élevé, mais nous pouvons réduire le nombre total de dataframes que nous créons. Lors de la modification de votre dataframe, préférez
inplace=True
, afin de ne pas créer de copies.Un autre piège courant consiste à conserver des copies de dataframes précédemment créées dans ipython:
Vous pouvez résoudre ce problème en tapant
%reset Out
pour effacer votre historique. Vous pouvez également ajuster la quantité d'historique conservée par ipythonipython --cache-size=5
(la valeur par défaut est 1000).Réduction de la taille de Dataframe
Dans la mesure du possible, évitez d'utiliser des types d'objets.
Les valeurs avec un objet dtype sont encadrées, ce qui signifie que le tableau numpy contient juste un pointeur et que vous avez un objet Python complet sur le tas pour chaque valeur de votre dataframe. Cela inclut les chaînes.
Alors que numpy prend en charge les chaînes de taille fixe dans les tableaux, les pandas ne le font pas ( cela a causé une confusion chez l'utilisateur ). Cela peut faire une différence significative:
Vous souhaiterez peut-être éviter d'utiliser des colonnes de chaîne ou trouver un moyen de représenter les données de chaîne sous forme de nombres.
Si vous avez une trame de données qui contient de nombreuses valeurs répétées (NaN est très courant), vous pouvez utiliser une structure de données éparse pour réduire l'utilisation de la mémoire:
Affichage de l'utilisation de la mémoire
Vous pouvez afficher l'utilisation de la mémoire ( docs ):
Depuis pandas 0.17.1, vous pouvez également
df.info(memory_usage='deep')
voir l'utilisation de la mémoire, y compris les objets.la source
Comme indiqué dans les commentaires, il y a certaines choses à essayer:
gc.collect
(@EdChum) peut effacer des choses, par exemple. Au moins d'après mon expérience, ces choses fonctionnent parfois et souvent pas.Cependant, il y a une chose qui fonctionne toujours, car elle est effectuée au niveau du système d'exploitation, et non au niveau de la langue.
Supposons que vous ayez une fonction qui crée un énorme DataFrame intermédiaire et renvoie un résultat plus petit (qui peut également être un DataFrame):
Ensuite, si vous faites quelque chose comme
Ensuite, la fonction est exécutée à un processus différent . Une fois ce processus terminé, le système d'exploitation reprend toutes les ressources qu'il a utilisées. Il n'y a vraiment rien que Python, pandas, le ramasse-miettes, puisse faire pour arrêter cela.
la source
with multiprocessing.Pool(1) as pool: result = pool.map(huge_intermediate_calc, [something])
faut fermer le pool une fois terminé.Cela résout le problème de la libération de la mémoire pour moi !!!
la trame de données sera explicitement définie sur null
la source
del df
ne sera pas supprimé s'il y a une référence audf
au moment de la suppression. Vous devez donc supprimer toutes les références à celui-ci avecdel df
pour libérer la mémoire.Ainsi, toutes les instances liées à df doivent être supprimées pour déclencher le garbage collection.
Utilisez objgragh pour vérifier ce qui retient les objets.
la source
Il semble qu'il y ait un problème avec la glibc qui affecte l'allocation de mémoire dans Pandas: https://github.com/pandas-dev/pandas/issues/2659
Le patch de singe détaillé sur ce problème a résolu le problème pour moi:
la source