Me he estado preguntando ... Si estoy leyendo, digamos, un archivo csv de 400 MB en un marco de datos de pandas (usando read_csv o read_table), ¿hay alguna forma de estimar cuánta memoria necesitará? Solo intento tener una mejor idea de los marcos de datos y la memoria ...
125
top
y despuésShift + M
de ordenar mi uso de la memoria.x=df.loc[[]]
tarda unos0.1
segundos en calcularse (para extraer cero filas) y, además, ocupa cientos de megabytes de memoria, al igual que el marco de datos original, probablemente debido a algunas copias debajo.Respuestas:
df.memory_usage()
devolverá cuánto ocupa cada columna:Para incluir índices, pase
index=True
.Entonces, para obtener el consumo total de memoria:
Además, la aprobación
deep=True
permitirá un informe de uso de memoria más preciso, que representa el uso completo de los objetos contenidos.Esto se debe a que el uso de memoria no incluye la memoria consumida por elementos que no son componentes de la matriz if
deep=False
(caso predeterminado).fuente
deep=True
deep=True
memory_usage()
devuelve el uso de memoria en bytes (como era de esperar).Aquí hay una comparación de los diferentes métodos:
sys.getsizeof(df)
es el más simple.Para este ejemplo,
df
es un marco de datos con 814 filas, 11 columnas (2 entradas, 9 objetos) - leído de un shapefile de 427kbsys.getsizeof (df)
df.memory_usage ()
df.info ()
Imprime la información del marco de datos en la salida estándar. Técnicamente, estos son kibibytes (KiB), no kilobytes, como dice la cadena de documentos, "El uso de la memoria se muestra en unidades legibles por humanos (representación en base 2)". Entonces, para obtener bytes se multiplicaría por 1024, por ejemplo, 451.6 KiB = 462,438 bytes.
fuente
g
refiere el código anterior?df.info(memory_usage="deep")
, devuelve "392.6 MB", mientras quesys.getsizeof(df)
ydf.memory_usage(index=True, deep=True).sum()
ambos vuelven aproximadamente "411 718 016" (~ 411MB). ¿Puede explicar por qué los 3 resultados no son consistentes? graciasdf.memory_usage(deep=True).sum()
devuelve casi lo mismo condf.memory_usage(index=True, deep=True).sum()
. en mi caso,index
no ocupa mucha memoria. Curiosamente, descubrí que411718016/1024/1024 = 392.6
, por lo quedf.info(memory_usage="deep")
puede usar2^10
para convertir bytes a MB , lo que me confunde. Gracias por tu ayuda de todos modos: D.df.info
devuelve mebibytes (2 ^ 10), no megabytes (10 ^ 6) - modificará la respuesta.Pensé que aportaría más datos a la discusión.
Realicé una serie de pruebas sobre este tema.
Al usar el
resource
paquete python obtuve el uso de memoria de mi proceso.Y escribiendo el csv en un
StringIO
búfer, pude medir fácilmente su tamaño en bytes.Ejecuté dos experimentos, cada uno creando 20 marcos de datos de tamaños crecientes entre 10,000 líneas y 1,000,000 de líneas. Ambos tienen 10 columnas.
En el primer experimento, usé solo flotantes en mi conjunto de datos.
Así es como la memoria aumentó en comparación con el archivo csv en función del número de líneas. (Tamaño en megabytes)
En el segundo experimento tuve el mismo enfoque, pero los datos en el conjunto de datos consistían solo en cadenas cortas.
Parece que la relación entre el tamaño del csv y el tamaño del marco de datos puede variar bastante, pero el tamaño en la memoria siempre será mayor en un factor de 2-3 (para los tamaños de marco en este experimento)
Me encantaría completar esta respuesta con más experimentos, comenta si quieres que pruebe algo especial.
fuente
Tienes que hacer esto al revés.
Técnicamente, la memoria se trata de esto (que incluye los índices)
Entonces, 168 MB de memoria con un archivo de 400 MB, 1 millón de filas de 20 columnas flotantes
MUCHO más compacto cuando se escribe como un archivo HDF5 binario
Los datos eran aleatorios, por lo que la compresión no ayuda demasiado
fuente
read_csv
?iotop
gustatop
/htop
para ver (en tiempo real) el rendimiento de E / S.nbytes
será una gran subestimación si tiene, por ejemplo, cadenas en un marco de datos.Si conoce los
dtype
s de su matriz, puede calcular directamente la cantidad de bytes que se necesitarán para almacenar sus datos + algunos para los objetos Python en sí. Un atributo útil de lasnumpy
matrices esnbytes
. Puede obtener el número de bytes de las matrices en un pandasDataFrame
haciendoobject
Las matrices dtype almacenan 8 bytes por objeto (las matrices dtype de objeto almacenan un puntero a un opacoPyObject
), por lo que si tiene cadenas en su csv, debe tener en cuenta que lasread_csv
convertirá enobject
matrices dtype y ajustará sus cálculos en consecuencia.EDITAR:
Consulte la
numpy
página de tipos escalares para obtener más detalles sobreobject
dtype
. Dado que solo se almacena una referencia, también debe tener en cuenta el tamaño del objeto en la matriz. Como dice esa página, las matrices de objetos son algo similares a loslist
objetos de Python .fuente
Sí hay. Pandas almacenará sus datos en
ndarray
estructuras numéricas bidimensionales agrupándolos por tipos.ndarray
es básicamente una matriz de datos en C sin procesar con un encabezado pequeño. Por lo tanto, puede estimar su tamaño simplemente multiplicando el tamañodtype
que contiene por las dimensiones de la matriz.Por ejemplo: si tiene 1000 filas con 2
np.int32
y 5np.float64
columnas, su DataFrame tendrá unanp.int32
matriz 2x1000 y unanp.float64
matriz 5x1000 que es:4bytes * 2 * 1000 + 8bytes * 5 * 1000 = 48000 bytes
fuente
DataFrame
?pandas
tiene una implementación muy eficienteread_table
en Cython (es mucho mejor que el loadtxt de numpy), así que supongo que analiza y almacena los datos directamente enndarray
.Creo que esto le da el tamaño en memoria a cualquier objeto en Python. Es necesario comprobar los componentes internos con respecto a los pandas y numpy
fuente