La forma más rápida de leer entrada en Python

Quiero leer un archivo de texto enorme que contiene una lista de listas de enteros. Ahora estoy haciendo lo siguiente:

G = [] with open("test.txt", 'r') as f: for line in f: G.append(list(map(int,line.split()))) 

Sin embargo, tarda unos 17 segundos (a través de timeit). ¿Hay alguna manera de reducir este tiempo? Tal vez, hay una manera de no usar el mapa.

numpy tiene las funciones loadtxt y genfromtxt , pero ninguna es particularmente rápida. Uno de los lectores de texto más rápidos disponibles en una biblioteca ampliamente distribuida es la función read_csv en pandas ( http://pandas.pydata.org/ ). En mi computadora, leer 5 millones de líneas que contienen dos enteros por línea toma aproximadamente 46 segundos con numpy.loadtxt , 26 segundos con numpy.genfromtxt y un poco más de 1 segundo con pandas.read_csv .

Aquí está la sesión mostrando el resultado. (Esto es en Linux, Ubuntu 12.04 64 bit. No puede verlo aquí, pero después de cada lectura del archivo, la memoria caché del disco se borró ejecutando sync; echo 3 > /proc/sys/vm/drop_caches en una sync; echo 3 > /proc/sys/vm/drop_caches separada shell.)

 In [1]: import pandas as pd In [2]: %timeit -n1 -r1 loadtxt('junk.dat') 1 loops, best of 1: 46.4 s per loop In [3]: %timeit -n1 -r1 genfromtxt('junk.dat') 1 loops, best of 1: 26 s per loop In [4]: %timeit -n1 -r1 pd.read_csv('junk.dat', sep=' ', header=None) 1 loops, best of 1: 1.12 s per loop 

pandas que se basa en numpy tiene un analizador de archivos basado en C que es muy rápido:

 # generate some integer data (5 M rows, two cols) and write it to file In [24]: data = np.random.randint(1000, size=(5 * 10**6, 2)) In [25]: np.savetxt('testfile.txt', data, delimiter=' ', fmt='%d') # your way In [26]: def your_way(filename): ...: G = [] ...: with open(filename, 'r') as f: ...: for line in f: ...: G.append(list(map(int, line.split(',')))) ...: return G ...: In [26]: %timeit your_way('testfile.txt', ' ') 1 loops, best of 3: 16.2 s per loop In [27]: %timeit pd.read_csv('testfile.txt', delimiter=' ', dtype=int) 1 loops, best of 3: 1.57 s per loop 

Entonces, pandas.read_csv tarda aproximadamente un segundo y medio en leer sus datos y es aproximadamente 10 veces más rápido que su método.

Como regla general (para casi cualquier idioma), usar read() para leer todo el archivo será más rápido que leer una línea a la vez. Si no está limitado por la memoria, lea todo el archivo de una vez y luego divida los datos en nuevas líneas, luego repita la lista de líneas.

La aceleración más fácil sería ir a PyPy http://pypy.org/

El siguiente problema es NO leer el archivo (si es posible). En su lugar, procesarlo como una secuencia.

Las comprensiones en lista son a menudo más rápidas.

 G = [[int(item) item in line.split()] for line in f] 

Más allá de eso, prueba PyPy y Cython y numpy

También puede intentar llevar los datos a una base de datos a través de inserciones masivas y luego procesar sus registros con las operaciones establecidas. Dependiendo de lo que tenga que hacer, eso puede ser más rápido, ya que el software de inserción masiva está optimizado para este tipo de tarea.