read python memory csv numpy scipy

python - read - genfromtxt



Python sin memoria en un archivo CSV grande(numpy) (3)

Tengo un archivo CSV de 3GB que trato de leer con Python, necesito la columna de la mediana.

from numpy import * def data(): return genfromtxt(''All.csv'',delimiter='','') data = data() # This is where it fails already. med = zeros(len(data[0])) data = data.T for i in xrange(len(data)): m = median(data[i]) med[i] = 1.0/float(m) print med

El error que obtengo es esto:

Python(1545) malloc: *** mmap(size=16777216) failed (error code=12) *** error: can''t allocate region *** set a breakpoint in malloc_error_break to debug Traceback (most recent call last): File "Normalize.py", line 40, in <module> data = data() File "Normalize.py", line 39, in data return genfromtxt(''All.csv'',delimiter='','') File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site- packages/numpy/lib/npyio.py", line 1495, in genfromtxt for (i, line) in enumerate(itertools.chain([first_line, ], fhd)): MemoryError

Creo que es solo un error de memoria. Estoy ejecutando un MacOSX de 64 bits con 4 GB de RAM y ambos numpy y Python compilados en modo de 64 bits.

¿Cómo puedo solucionar esto? ¿Debo intentar un enfoque distribuido, solo para la gestión de la memoria?

Gracias

EDITAR: También intenté con esto, pero no tuve suerte ...

genfromtxt(''All.csv'',delimiter='','', dtype=float16)


¿Por qué no estás usando el módulo python csv ?

>> import csv >> reader = csv.reader(open(''All.csv'')) >>> for row in reader: ... print row


Como otras personas han mencionado, para un archivo realmente grande, es mejor repetirlo.

Sin embargo, comúnmente quiere que todo esté en la memoria por varias razones.

genfromtxt es mucho menos eficiente que loadtxt (aunque maneja datos faltantes, mientras que loadtxt es más "pobre y malo", por lo que las dos funciones coexisten).

Si sus datos son muy regulares (por ejemplo, solo filas delimitadas simples de todo el mismo tipo), también puede mejorar utilizando numpy.fromiter .

Si tiene suficiente memoria RAM, considere usar np.loadtxt(''yourfile.txt'', delimiter='','') (También puede necesitar especificar skiprows si tiene un encabezado en el archivo).

Como una comparación rápida, cargar ~ 500MB de archivo de texto con loadtxt usa ~ 900MB de ram en el uso máximo, mientras que cargar el mismo archivo con genfromtxt usa ~ 2.5GB.

Loadtxt

Genfromtxt

Alternativamente, considere algo como lo siguiente. Solo funcionará para datos muy simples y regulares, pero es bastante rápido. ( loadtxt y genfromtxt hacen muchas conjeturas y verifican errores. Si sus datos son muy simples y regulares, puede mejorarlos mucho).

import numpy as np def generate_text_file(length=1e6, ncols=20): data = np.random.random((length, ncols)) np.savetxt(''large_text_file.csv'', data, delimiter='','') def iter_loadtxt(filename, delimiter='','', skiprows=0, dtype=float): def iter_func(): with open(filename, ''r'') as infile: for _ in range(skiprows): next(infile) for line in infile: line = line.rstrip().split(delimiter) for item in line: yield dtype(item) iter_loadtxt.rowlength = len(line) data = np.fromiter(iter_func(), dtype=dtype) data = data.reshape((-1, iter_loadtxt.rowlength)) return data #generate_text_file() data = iter_loadtxt(''large_text_file.csv'')

Fromiter


El problema con el uso de genfromtxt () es que intenta cargar todo el archivo en la memoria, es decir, en una matriz numpy. Esto es ideal para archivos pequeños pero MALO para entradas de 3GB como la tuya. Como solo calcula las medianas de la columna, no es necesario leer todo el archivo. Una forma simple, pero no la manera más eficiente de hacerlo, sería leer todo el archivo línea por línea varias veces e iterar sobre las columnas.