Actualmente estoy tratando de leer datos de archivos .csv en Python 2.7 con hasta 1 millón de filas y 200 columnas (los archivos oscilan entre 100 MB y 1,6 GB). Puedo hacer esto (muy lentamente) para los archivos con menos de 300,000 filas, pero una vez que voy por encima de eso, obtengo errores de memoria. Mi código se ve así:
def getdata(filename, criteria):
data=[]
for criterion in criteria:
data.append(getstuff(filename, criteron))
return data
def getstuff(filename, criterion):
import csv
data=[]
with open(filename, "rb") as csvfile:
datareader=csv.reader(csvfile)
for row in datareader:
if row[3]=="column header":
data.append(row)
elif len(data)<2 and row[3]!=criterion:
pass
elif row[3]==criterion:
data.append(row)
else:
return data
El motivo de la cláusula else en la función getstuff es que todos los elementos que se ajustan al criterio se enumerarán juntos en el archivo csv, así que dejo el bucle cuando los supere para ahorrar tiempo.
Mis preguntas son:
¿Cómo puedo hacer que esto funcione con archivos más grandes?
¿Hay alguna forma de hacerlo más rápido?
Mi computadora tiene 8 GB de RAM, ejecuta Windows 7 de 64 bits y el procesador es de 3,40 GHz (no estoy seguro de qué información necesita).
fuente
Respuestas:
Estás leyendo todas las filas en una lista y luego procesando esa lista. No hagas eso .
Procese sus filas a medida que las produce. Si primero necesita filtrar los datos, use una función de generador:
También simplifiqué su prueba de filtro; la lógica es la misma pero más concisa.
Debido a que solo está haciendo coincidir una única secuencia de filas que coinciden con el criterio, también puede usar:
Ahora puede recorrer
getstuff()
directamente. Haz lo mismo engetdata()
:Ahora repita directamente
getdata()
su código:Ahora solo tiene una fila en la memoria, en lugar de sus miles de líneas por criterio.
yield
convierte una función en una función generadora , lo que significa que no funcionará hasta que empiece a recorrerla.fuente
csv.DictReader
? Porque mis pruebas en un archivo .csv de 2.5GB muestran que intentar iterar fila por fila como esta cuando se usa eso en lugar decsv.reader
hace que el proceso de Python crezca hasta el uso total de memoria de 2.5GB.Aunque la respuesta de Martijin es probablemente la mejor. Aquí hay una forma más intuitiva de procesar archivos csv grandes para principiantes. Esto le permite procesar grupos de filas o fragmentos a la vez.
fuente
Hago una buena cantidad de análisis de vibraciones y miro grandes conjuntos de datos (decenas y cientos de millones de puntos). Mis pruebas mostraron que la función pandas.read_csv () es 20 veces más rápida que numpy.genfromtxt (). Y la función genfromtxt () es 3 veces más rápida que numpy.loadtxt (). Parece que necesitas pandas para grandes conjuntos de datos.
Publiqué el código y los conjuntos de datos que usé en esta prueba en un blog en el que se discutía MATLAB vs Python para el análisis de vibraciones .
fuente
lo que funcionó para mí fue y es superrápido es
Otra solución de trabajo es:
fuente
df_train=df_train.compute()
carga la línea en su primera solución todo el conjunto de datos en la memoria ... que es lo que está tratando de no hacer?Para alguien que aterriza en esta pregunta. El uso de pandas con ' chunksize ' y ' usecols ' me ayudó a leer un archivo zip enorme más rápido que las otras opciones propuestas.
fuente
aquí hay otra solución para Python3:
aquí
datareader
hay una función de generador.fuente
Si está usando pandas y tiene mucha RAM (suficiente para leer todo el archivo en la memoria) intente usar
pd.read_csv
conlow_memory=False
, por ejemplo:fuente