Estoy tratando de leer un archivo csv grande (aprox. 6 GB) en pandas y recibo un error de memoria:
MemoryError Traceback (most recent call last)
<ipython-input-58-67a72687871b> in <module>()
----> 1 data=pd.read_csv('aphro.csv',sep=';')
...
MemoryError:
¿Alguna ayuda en esto?
Respuestas:
El error muestra que la máquina no tiene suficiente memoria para leer todo el CSV en un DataFrame al mismo tiempo. Suponiendo que no necesita todo el conjunto de datos en la memoria al mismo tiempo, una forma de evitar el problema sería procesar el CSV en fragmentos (especificando el
chunksize
parámetro):El
chunksize
parámetro especifica el número de filas por fragmento. (El último fragmento puede contener menos quechunksize
filas, por supuesto).fuente
DF.append(chunk)
dentro del bucle. Eso usaráO(N^2)
operaciones de copia. Es mejor para anexar los datos agregados a una lista , y luego construir la trama de datos de la lista con una llamada apd.DataFrame
opd.concat
(dependiendo del tipo de datos agregados).DF.append(chunk)
en bucle requiereO(N^2)
operaciones de copia dondeN
está el tamaño de los fragmentos, porque cada llamada aDF.append
devuelve un nuevo DataFrame. Llamarpd.DataFrame
opd.concat
una vez fuera del bucle reduce la cantidad de copiasO(N)
.chunksize
parámetro se refiere al número de filas por trozo. El último fragmento puede contener menos quechunksize
filas, por supuesto.pd.concat([list_of_dfs])
una vez después del ciclo es mucho más rápido que llamarpd.concat
odf.append
muchas veces dentro del ciclo. Por supuesto, necesitará una cantidad considerable de memoria para mantener todo el csv de 6GB como un DataFrame.La fragmentación no siempre debe ser el primer puerto de escala para este problema.
¿El archivo es grande debido a datos no numéricos repetidos o columnas no deseadas?
Si es así, a veces puede ver grandes ahorros de memoria al leer las columnas como categorías y seleccionar las columnas requeridas a través del parámetro pd.read_csv
usecols
.¿Su flujo de trabajo requiere cortar, manipular, exportar?
Si es así, puede usar dask.dataframe para cortar, realizar sus cálculos y exportar iterativamente. El fragmentación se realiza en silencio por dask, que también admite un subconjunto de pandas API.
Si todo lo demás falla, lea línea por línea a través de fragmentos.
Trozo a través de pandas o a través de la biblioteca csv como último recurso.
fuente
Procedí así:
fuente
read_csv
aread_table
?Para datos grandes, le recomiendo que use la biblioteca "dask",
por ejemplo:
Puede leer más de la documentación aquí .
Otra gran alternativa sería usar modin porque toda la funcionalidad es idéntica a la de los pandas, pero aprovecha las bibliotecas de marcos de datos distribuidos como dask.
fuente
La respuesta anterior ya está satisfaciendo el tema. De todos modos, si necesita todos los datos en la memoria, eche un vistazo a bcolz . Está comprimiendo los datos en la memoria. He tenido muy buena experiencia con eso. Pero le faltan muchas características de pandas
Editar: Obtuve tasas de compresión de aproximadamente 1/10 o el tamaño original, creo, por supuesto, dependiendo del tipo de datos. Las características importantes que faltaban eran los agregados.
fuente
chunks
método mencionado, luego usar bcolz si necesita todos los datos en la memoria para hacer un análisis. Solo un pensamiento.Puede leer los datos como fragmentos y guardar cada fragmento como pepinillo.
En el siguiente paso, lea los encurtidos y agregue cada encurtido a su marco de datos deseado.
fuente
df
ajuste final se ajusta completamente en la memoria (como está implícito) y contiene la misma cantidad de datos que su entrada, ¿seguramente no necesitará trocear en absoluto?La función read_csv y read_table es casi la misma. Pero debe asignar el delimitador "," cuando utiliza la función read_table en su programa.
fuente
Solución 1:
Usar pandas con datos grandes
Solución 2:
fuente
dfList.append
, solo procesa cada fragmento (df
) por separadoAquí sigue un ejemplo:
fuente
Puede probar sframe, que tiene la misma sintaxis que los pandas pero le permite manipular archivos que son más grandes que su RAM.
fuente
Si usa pandas, lea un archivo grande en trozos y luego ceda fila por fila, esto es lo que he hecho
fuente
Quiero dar una respuesta más completa basada en la mayoría de las posibles soluciones que ya se proporcionan. También quiero señalar una ayuda potencial más que puede ayudar al proceso de lectura.
Opción 1: dtypes
"dtypes" es un parámetro bastante poderoso que puede usar para reducir la presión de memoria de los
read
métodos. Mira esto y esto respuesta. Los pandas, por defecto, intentan inferir tipos de datos.En referencia a las estructuras de datos, cada dato almacenado tiene lugar una asignación de memoria. En un nivel básico, consulte los valores a continuación (la tabla siguiente ilustra los valores para el lenguaje de programación C):
Consulte esta página para ver la coincidencia entre los tipos NumPy y C.
Digamos que tiene una serie de enteros de dígitos . Puede asignar, teórica y prácticamente, una matriz de tipo entero de 16 bits, pero luego asignaría más memoria de la que realmente necesita para almacenar esa matriz. Para evitar esto, puede configurar la
dtype
opciónread_csv
. No desea almacenar los elementos de la matriz como un entero largo donde realmente puede ajustarlos con un entero de 8 bits (np.int8
onp.uint8
).Observe el siguiente mapa dtype.
Fuente: https://pbpython.com/pandas_dtypes.html
Puede pasar el
dtype
parámetro como un parámetro en los métodos pandas como dictar enread
{column: type}.Opción 2: Leer por fragmentos
La lectura de los datos en fragmentos le permite acceder a una parte de los datos en memoria, y puede aplicar el preprocesamiento en sus datos y preservar los datos procesados en lugar de los datos sin procesar. Sería mucho mejor si combina esta opción con la primera, dtypes .
Quiero señalar las secciones de libros de cocina de pandas para ese proceso, donde pueden encontrarlo aquí . Tenga en cuenta esas dos secciones allí;
Opción 3: Dask
Dask es un marco que se define en el sitio web de Dask como:
Nació para cubrir las partes necesarias donde los pandas no pueden alcanzar. Dask es un marco poderoso que le permite mucho más acceso a los datos al procesarlos de manera distribuida.
Puede usar dask para preprocesar sus datos en conjunto, Dask se encarga de la parte de fragmentación, por lo que, a diferencia de los pandas, puede definir sus pasos de procesamiento y dejar que Dask haga el trabajo. Dask no aplica los cálculos antes de que sea explícitamente empujado por
compute
y / opersist
(vea la respuesta aquí para ver la diferencia).Otras ayudas (ideas)
fuente
Además de las respuestas anteriores, para aquellos que desean procesar CSV y luego exportar a csv, parquet o SQL, d6tstack es otra buena opción. Puede cargar varios archivos y se ocupa de los cambios en el esquema de datos (columnas agregadas / eliminadas). Descompuesto del soporte principal ya está integrado.
fuente
En caso de que alguien todavía esté buscando algo como esto, descubrí que esta nueva biblioteca llamada modin puede ayudar. Utiliza computación distribuida que puede ayudar con la lectura. Aquí hay un buen artículo que compara su funcionalidad con los pandas. Básicamente usa las mismas funciones que los pandas.
fuente
modin
compara con el bien establecidodask.dataframe
? Por ejemplo, vea pasar de pandas a dask para utilizar todos los núcleos de CPU locales .Antes de usar la opción chunksize, si desea estar seguro sobre la función de proceso que desea escribir dentro del bucle for de chunking como lo menciona @unutbu, simplemente puede usar la opción nrows.
Una vez que esté seguro de que el bloque de proceso está listo, puede ponerlo en el bucle de fragmentación para todo el marco de datos.
fuente