Publiqué esta pregunta porque me preguntaba si hice algo terriblemente mal para obtener este resultado.
Tengo un archivo csv de tamaño mediano y traté de usar numpy para cargarlo. Para ilustrar, hice el archivo usando python:
import timeit import numpy as np my_data = np.random.rand(1500000, 3)*10 np.savetxt('./test.csv', my_data, delimiter=',', fmt='%.2f')
Y luego, probé dos métodos: numpy.genfromtxt, numpy.loadtxt
setup_stmt = 'import numpy as np' stmt1 = """\ my_data = np.genfromtxt('./test.csv', delimiter=',') """ stmt2 = """\ my_data = np.loadtxt('./test.csv', delimiter=',') """ t1 = timeit.timeit(stmt=stmt1, setup=setup_stmt, number=3) t2 = timeit.timeit(stmt=stmt2, setup=setup_stmt, number=3)
Y el resultado muestra que t1 = 32.159652940464184, t2 = 52.00093725634724 .
Sin embargo, cuando intenté usar matlab:
tic for i = 1:3 my_data = dlmread('./test.csv'); end toc
El resultado muestra: El tiempo transcurrido es 3.196465 segundos .
Entiendo que puede haber algunas diferencias en la velocidad de carga, pero:
Cualquier entrada sería apreciada. ¡Muchas gracias por adelantado!
Sí, la lectura de archivos csv
en numpy
es bastante lenta. Hay una gran cantidad de Python puro a lo largo de la ruta del código. En estos días, incluso cuando estoy usando numpy
puros, todavía uso pandas
para IO:
>>> import numpy as np, pandas as pd >>> %time d = np.genfromtxt("./test.csv", delimiter=",") CPU times: user 14.5 s, sys: 396 ms, total: 14.9 s Wall time: 14.9 s >>> %time d = np.loadtxt("./test.csv", delimiter=",") CPU times: user 25.7 s, sys: 28 ms, total: 25.8 s Wall time: 25.8 s >>> %time d = pd.read_csv("./test.csv", delimiter=",").values CPU times: user 740 ms, sys: 36 ms, total: 776 ms Wall time: 780 ms
Alternativamente, en un caso tan simple como este, podrías usar algo como lo que Joe Kington escribió aquí :
>>> %time data = iter_loadtxt("test.csv") CPU times: user 2.84 s, sys: 24 ms, total: 2.86 s Wall time: 2.86 s
También está la biblioteca de lectores de texto de Warren Weckesser, en caso de que los pandas
sean una dependencia demasiado pesada:
>>> import textreader >>> %time d = textreader.readrows("test.csv", float, ",") readrows: numrows = 1500000 CPU times: user 1.3 s, sys: 40 ms, total: 1.34 s Wall time: 1.34 s
Si solo desea guardar y leer una matriz numpy, es mucho mejor guardarlo como binario o binario comprimido según el tamaño:
my_data = np.random.rand(1500000, 3)*10 np.savetxt('./test.csv', my_data, delimiter=',', fmt='%.2f') np.save('./testy', my_data) np.savez('./testz', my_data) del my_data setup_stmt = 'import numpy as np' stmt1 = """\ my_data = np.genfromtxt('./test.csv', delimiter=',') """ stmt2 = """\ my_data = np.load('./testy.npy') """ stmt3 = """\ my_data = np.load('./testz.npz')['arr_0'] """ t1 = timeit.timeit(stmt=stmt1, setup=setup_stmt, number=3) t2 = timeit.timeit(stmt=stmt2, setup=setup_stmt, number=3) t3 = timeit.timeit(stmt=stmt3, setup=setup_stmt, number=3) genfromtxt 39.717250824 save 0.0667860507965 savez 0.268463134766
Quizás es mejor instalar un código c simple que convierte los datos a binarios y hacer que ‘numpy’ lea el archivo binario. Tengo un archivo CSV de 20 GB para leer, ya que los datos CSV son una mezcla de int, double, str. La lectura de conjuntos de estructuras con bultos lleva más de una hora, mientras que el volcado a binario tomó aproximadamente 2 minutos y la carga a numpy toma menos de 2 segundos.
Mi código específico, por ejemplo, está disponible aquí .
FWIW el módulo csv incorporado funciona muy bien y realmente no es tan detallado.
modulo csv:
%%timeit with open('test.csv', 'r') as f: np.array([l for l in csv.reader(f)]) 1 loop, best of 3: 1.62 s per loop
np.loadtext
:
%timeit np.loadtxt('test.csv', delimiter=',') 1 loop, best of 3: 16.6 s per loop
pd.read_csv
:
%timeit pd.read_csv('test.csv', header=None).values 1 loop, best of 3: 663 ms per loop
Personalmente, me gusta usar pandas read_csv
pero el módulo csv es bueno cuando estoy usando números puros.