Tengo un archivo csv realmente grande que abrí en pandas de la siguiente manera ...
import pandas
df = pandas.read_csv('large_txt_file.txt')
Una vez que hago esto, mi uso de memoria aumenta en 2 GB, lo que se espera porque este archivo contiene millones de filas. Mi problema viene cuando necesito liberar esta memoria. Corrí ...
del df
Sin embargo, mi uso de memoria no disminuyó. ¿Es este el enfoque incorrecto para liberar la memoria utilizada por un marco de datos de pandas? Si es así, ¿cuál es la forma correcta?
gc
módulo y llamar,gc.collect()
pero es posible que no recupere la memoriadel df
no se llama directamente después de la creación de df, ¿verdad? Creo que hay referencias al df en el momento en que elimina el df. Por lo tanto, no se eliminará, sino que eliminará el nombre.df = ''
al final de su código? Parece borrar la RAM utilizada por el marco de datos.Respuestas:
Reducir el uso de memoria en Python es difícil, porque Python en realidad no libera memoria al sistema operativo . Si elimina objetos, la memoria estará disponible para nuevos objetos de Python, pero no
free()
volverá al sistema ( consulte esta pregunta ).Si se adhiere a matrices numéricas numéricas, esas se liberan, pero los objetos en caja no.
Reducir el número de marcos de datos
Python mantiene nuestra memoria en una marca de agua alta, pero podemos reducir la cantidad total de marcos de datos que creamos. Al modificar su marco de datos, prefiera
inplace=True
, para que no cree copias.Otro problema común es aferrarse a copias de marcos de datos creados previamente en ipython:
Puede solucionar este problema escribiendo
%reset Out
para borrar su historial. Alternativamente, puede ajustar la cantidad de historial que guarda ipythonipython --cache-size=5
(el valor predeterminado es 1000).Reducir el tamaño del marco de datos
Siempre que sea posible, evite el uso de tipos de objetos.
Los valores con un tipo de objeto están encuadrados, lo que significa que la matriz numpy solo contiene un puntero y tienes un objeto Python completo en el montón para cada valor en tu marco de datos. Esto incluye cadenas.
Si bien numpy admite cadenas de tamaño fijo en matrices, pandas no lo hace ( ha causado confusión en el usuario ). Esto puede marcar una diferencia significativa:
Es posible que desee evitar el uso de columnas de cadena o encontrar una forma de representar los datos de cadena como números.
Si tiene un marco de datos que contiene muchos valores repetidos (NaN es muy común), entonces puede usar una estructura de datos dispersa para reducir el uso de memoria:
Visualización del uso de memoria
Puede ver el uso de memoria ( documentos ):
A partir de pandas 0.17.1, también puede hacer
df.info(memory_usage='deep')
para ver el uso de la memoria, incluidos los objetos.fuente
Como se señaló en los comentarios, hay algunas cosas que puede probar:
gc.collect
(@EdChum) puede borrar cosas, por ejemplo. Al menos desde mi experiencia, estas cosas a veces funcionan y a menudo no.Sin embargo, hay una cosa que siempre funciona porque se hace en el sistema operativo, no en el idioma.
Supongamos que tiene una función que crea un DataFrame enorme intermedio y devuelve un resultado más pequeño (que también podría ser un DataFrame):
Entonces si haces algo como
Luego, la función se ejecuta en un proceso diferente . Cuando se completa ese proceso, el sistema operativo retoma todos los recursos que utilizó. Realmente no hay nada que Python, pandas, el recolector de basura, puedan hacer para detener eso.
fuente
with multiprocessing.Pool(1) as pool: result = pool.map(huge_intermediate_calc, [something])
que implica cerrar el grupo una vez hecho.¡Esto resuelve el problema de liberarme la memoria!
el marco de datos se establecerá explícitamente en nulo
fuente
del df
no se eliminará si hay alguna referencia aldf
en el momento de la eliminación. Por lo tanto, debe eliminar todas las referenciasdel df
para liberar la memoria.Por lo tanto, todas las instancias vinculadas a df deben eliminarse para activar la recolección de basura.
Utilice objgragh para comprobar cuál está sujetando los objetos.
fuente
Parece que hay un problema con glibc que afecta la asignación de memoria en Pandas: https://github.com/pandas-dev/pandas/issues/2659
El parche de mono detallado sobre este problema me ha resuelto el problema:
fuente