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

topy despuésShift + Mde ordenar mi uso de la memoria.x=df.loc[[]]tarda unos0.1segundos 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=Truepermitirá 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=Truedeep=Truememory_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,
dfes 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
grefiere 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,indexno ocupa mucha memoria. Curiosamente, descubrí que411718016/1024/1024 = 392.6, por lo quedf.info(memory_usage="deep")puede usar2^10para convertir bytes a MB , lo que me confunde. Gracias por tu ayuda de todos modos: D.df.infodevuelve 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
resourcepaquete python obtuve el uso de memoria de mi proceso.Y escribiendo el csv en un
StringIObú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?iotopgustatop/htoppara ver (en tiempo real) el rendimiento de E / S.nbytesserá una gran subestimación si tiene, por ejemplo, cadenas en un marco de datos.Si conoce los
dtypes 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 lasnumpymatrices esnbytes. Puede obtener el número de bytes de las matrices en un pandasDataFramehaciendoobjectLas 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_csvconvertirá enobjectmatrices dtype y ajustará sus cálculos en consecuencia.EDITAR:
Consulte la
numpypágina de tipos escalares para obtener más detalles sobreobjectdtype. 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 loslistobjetos de Python .fuente
Sí hay. Pandas almacenará sus datos en
ndarrayestructuras numéricas bidimensionales agrupándolos por tipos.ndarrayes 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ñodtypeque contiene por las dimensiones de la matriz.Por ejemplo: si tiene 1000 filas con 2
np.int32y 5np.float64columnas, su DataFrame tendrá unanp.int32matriz 2x1000 y unanp.float64matriz 5x1000 que es:4bytes * 2 * 1000 + 8bytes * 5 * 1000 = 48000 bytes
fuente
DataFrame?pandastiene una implementación muy eficienteread_tableen 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