es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Memoria agotada al leer un archivo CSV con Python.

Pregunta 1.

Intenté leer un archivo CSV de aproximadamente 1GB como se muestra a continuación:

import csv

res = []
with open("my_csv.csv", "r") as f:
    reader = csv.reader(f)
    for row in reader:
        res.append(row)

Pensé que 1GB era lo suficientemente pequeño como para cargarlo en memoria como una lista. Pero de hecho, el código se congela y el uso de memoria era del 100%. Había verificado que la memoria adicional disponible era de algunos GB antes de ejecutar el código.

Esta respuesta dice:

“Estás leyendo todas las filas en una lista y luego procesando esa lista.
No hagas eso.

Pero me pregunto POR QUÉ? ¿Por qué la lista ocupa mucha más memoria que el tamaño del archivo?


Pregunta 2.

¿Existe algún método para analizar un CSV en un diccionario sin problemas de memoria?

Por ejemplo,

CSV

apple,1,2,a    
apple,4,5,b    
banana,AAA,0,3    
kiwi,g1,g2,g3

Diccionario

{"apple" : [[1, 2, a], [4, 5, b]],
 "banana": [[AAA, 0, 3]],
 "kiwi"  : [[g1, g2, g3]]}
Tags:  ,

Answer

  1. Avatar for davy.ai

    Cuando lees el archivo CSV en una lista utilizando el código anterior, básicamente cargas todo el archivo en memoria de una vez. El uso de memoria de la lista será varias veces mayor que el tamaño del archivo, porque no solo estás almacenando los datos, sino también los objetos de Python y los gastos generales de gestión de memoria. Esto puede hacer que tu programa de Python se quede sin memoria o se congele, como en tu caso.

    Un enfoque mejor es leer el archivo línea por línea y procesar cada línea a medida que la lees. Esto te permite manejar archivos grandes sin cargarlos por completo en la memoria, y se conoce como “procesamiento de flujo”. Puedes hacer esto utilizando la clase csv.DictReader, que te permite iterar sobre las filas de un archivo CSV como diccionarios, sin cargar todo el archivo en la memoria. Aquí tienes un ejemplo:

    import csv
    
    with open("mi_csv.csv", "r") as f:
        reader = csv.DictReader(f)
        for row in reader:
            # procesa cada fila aquí
    

    En este ejemplo, csv.DictReader lee el archivo CSV una fila a la vez y devuelve cada fila como un diccionario (donde las claves son los encabezados de las columnas y los valores son los campos correspondientes). Luego puedes procesar cada fila a medida que la lees, en lugar de tener que almacenar todas las filas en la memoria de una vez.

    Respuesta 2:

    Sí, puedes analizar un CSV en un diccionario sin cargar todo el archivo en la memoria utilizando un enfoque similar de “procesamiento de flujo” al descrito anteriormente. Aquí tienes un ejemplo:

    import csv
    
    resultado = {}
    with open("mi_csv.csv", "r") as f:
        reader = csv.reader(f)
        for row in reader:
            # extrae la clave de la primera columna
            clave = row[0]
            # elimina la clave de la fila
            valor = row[1:]
            # agrega la fila al diccionario resultado bajo la clave apropiada
            if clave not in resultado:
                resultado[clave] = []
            resultado[clave].append(valor)
    

    En este ejemplo, inicializamos un diccionario vacío resultado y luego leemos el archivo CSV una fila a la vez utilizando csv.reader. Para cada fila, extraemos la clave de la primera columna y el resto de la fila se convierte en el valor. Luego agregamos el valor a una lista en el diccionario resultado bajo la clave apropiada. La instrucción if verifica si la clave ya existe en el diccionario y crea una nueva lista vacía si no existe.
    Este enfoque solo carga una fila a la vez en la memoria, por lo que puede manejar archivos muy grandes sin quedarse sin memoria.

Comments are closed.