¿Cómo leo datos CSV en una matriz de registros en NumPy?


415

Me pregunto si hay una forma directa de importar el contenido de un archivo CSV en una matriz de registro, tanto en la forma en que de R read.table(), read.delim()y read.csv()la importación de datos a la familia trama de datos de R?

¿O es la mejor manera de usar csv.reader () y luego aplicar algo como numpy.core.records.fromrecords()?


Respuestas:


647

Puede usar el genfromtxt()método de Numpy para hacerlo, estableciendo el delimiterkwarg en una coma.

from numpy import genfromtxt
my_data = genfromtxt('my_file.csv', delimiter=',')

Puede encontrar más información sobre la función en su documentación respectiva .


10
¿Qué pasa si quieres algo de diferentes tipos? ¿Como cuerdas e ints?
CGTheLegend

11
@CGTheLegend np.genfromtxt ('myfile.csv', delimiter = ',', dtype = None)
chickensoup

2
numpy.loadtxt también funcionó bastante bien para mí
Yibo Yang

11
Intenté esto pero solo obtengo nanvalores, ¿por qué? También con loadtxt, estoy obteniendo UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 155: ordinal not in range(128). Tengo diéresis como ä y ö en los datos de entrada.
hhh

1
@hhh intenta agregar encoding="utf8"argumento. Python es una de las pocas piezas de software modernas que con frecuencia causa problemas de codificación de texto, que se sienten como cosas del pasado.
kolen

187

Recomendaría la read_csvfunción de la pandasbiblioteca:

import pandas as pd
df=pd.read_csv('myfile.csv', sep=',',header=None)
df.values
array([[ 1. ,  2. ,  3. ],
       [ 4. ,  5.5,  6. ]])

Esto proporciona un DataFrame de pandas , que permite muchas funciones útiles de manipulación de datos que no están disponibles directamente con matrices de registros numpy .

DataFrame es una estructura de datos etiquetada bidimensional con columnas de tipos potencialmente diferentes. Puedes pensarlo como una hoja de cálculo o una tabla SQL ...


Yo también lo recomendaría genfromtxt. Sin embargo, dado que la pregunta solicita una matriz de registros , a diferencia de una matriz normal, el dtype=Noneparámetro debe agregarse a la genfromtxtllamada:

Dado un archivo de entrada, myfile.csv:

1.0, 2, 3
4, 5.5, 6

import numpy as np
np.genfromtxt('myfile.csv',delimiter=',')

da una matriz:

array([[ 1. ,  2. ,  3. ],
       [ 4. ,  5.5,  6. ]])

y

np.genfromtxt('myfile.csv',delimiter=',',dtype=None)

da una matriz de registros:

array([(1.0, 2.0, 3), (4.0, 5.5, 6)], 
      dtype=[('f0', '<f8'), ('f1', '<f8'), ('f2', '<i4')])

Esto tiene la ventaja de que el archivo con múltiples tipos de datos (incluidas las cadenas) se puede importar fácilmente .


read_csv funciona con comas entre comillas. Recomiende esto sobre genfromtxt
Viet

3
use header = 0 para omitir la primera línea en los valores, si su archivo tiene un encabezado de 1 línea
c-chavez

Tenga en cuenta que esto crea una matriz 2D: por ejemplo (1000, 1). np.genfromtxtno hace eso: ej (1000,).
Newskooler

74

Cronometré el

from numpy import genfromtxt
genfromtxt(fname = dest_file, dtype = (<whatever options>))

versus

import csv
import numpy as np
with open(dest_file,'r') as dest_f:
    data_iter = csv.reader(dest_f,
                           delimiter = delimiter,
                           quotechar = '"')
    data = [data for data in data_iter]
data_array = np.asarray(data, dtype = <whatever options>)

en 4.6 millones de filas con aproximadamente 70 columnas y descubrió que la ruta NumPy tomó 2 min 16 segundos y el método de comprensión de la lista csv tomó 13 segundos.

Recomendaría el método de comprensión csv-list, ya que probablemente se basa en bibliotecas precompiladas y no en el intérprete tanto como NumPy. Sospecho que el método de los pandas tendría una sobrecarga de intérprete similar.


23
Probé un código similar a este con un archivo csv que contiene 2.6 millones de filas y 8 columnas. numpy.recfromcsv () tardó aproximadamente 45 segundos, np.asarray (list (csv.reader ())) tardó aproximadamente 7 segundos y pandas.read_csv () tomó aproximadamente 2 segundos (!). (El archivo se había leído recientemente del disco en todos los casos, por lo que ya estaba en la caché de archivos del sistema operativo). Creo que iré con pandas.
Matthias Fripp

55
Acabo de notar que hay algunas notas sobre el diseño del analizador rápido de csv de pandas en wesmckinney.com/blog/… . El autor se toma muy en serio los requisitos de velocidad y memoria. También es posible usar as_recarray = True para obtener el resultado directamente como una matriz de registros de Python en lugar de un marco de datos de pandas.
Matthias Fripp

67

También puede probar recfromcsv()qué puede adivinar los tipos de datos y devolver una matriz de registros con el formato adecuado.


99
Si desea mantener los nombres de orden / columna en el CSV, puede usar la siguiente invocación: numpy.recfromcsv(fname, delimiter=',', filling_values=numpy.nan, case_sensitive=True, deletechars='', replace_space=' ')Los argumentos clave son los tres últimos.
eacousineau

16

Como probé en ambos sentidos usando NumPy y Pandas, usar pandas tiene muchas ventajas:

  • Más rápido
  • Menos uso de CPU
  • 1/3 de uso de RAM en comparación con NumPy genfromtxt

Este es mi código de prueba:

$ for f in test_pandas.py test_numpy_csv.py ; do  /usr/bin/time python $f; done
2.94user 0.41system 0:03.05elapsed 109%CPU (0avgtext+0avgdata 502068maxresident)k
0inputs+24outputs (0major+107147minor)pagefaults 0swaps

23.29user 0.72system 0:23.72elapsed 101%CPU (0avgtext+0avgdata 1680888maxresident)k
0inputs+0outputs (0major+416145minor)pagefaults 0swaps

test_numpy_csv.py

from numpy import genfromtxt
train = genfromtxt('/home/hvn/me/notebook/train.csv', delimiter=',')

test_pandas.py

from pandas import read_csv
df = read_csv('/home/hvn/me/notebook/train.csv')

Archivo de datos:

du -h ~/me/notebook/train.csv
 59M    /home/hvn/me/notebook/train.csv

Con NumPy y pandas en las versiones:

$ pip freeze | egrep -i 'pandas|numpy'
numpy==1.13.3
pandas==0.20.2

5

Puede usar este código para enviar datos del archivo CSV a una matriz:

import numpy as np
csv = np.genfromtxt('test.csv', delimiter=",")
print(csv)

4

Utilizando numpy.loadtxt

Un método bastante simple. Pero requiere que todos los elementos sean flotantes (int, etc.)

import numpy as np 
data = np.loadtxt('c:\\1.csv',delimiter=',',skiprows=0)  

4

Esta es la manera más fácil:

import csv with open('testfile.csv', newline='') as csvfile: data = list(csv.reader(csvfile))

Ahora cada entrada en los datos es un registro, representado como una matriz. Entonces tienes una matriz 2D. Me ahorró mucho tiempo.


¿Por qué deberíamos tener que jugar con Pandas, cuando estas herramientas tienen mucha menos función hinchada?
Christopher

3

Intenté esto:

import pandas as p
import numpy as n

closingValue = p.read_csv("<FILENAME>", usecols=[4], dtype=float)
print(closingValue)

3

Sugeriría usar tablas ( pip3 install tables). Puede guardar su .csvarchivo en .h5pandas ( pip3 install pandas),

import pandas as pd
data = pd.read_csv("dataset.csv")
store = pd.HDFStore('dataset.h5')
store['mydata'] = data
store.close()

Luego, puede cargar fácilmente sus datos en una matriz NumPy , y con menos tiempo incluso para una gran cantidad de datos .

import pandas as pd
store = pd.HDFStore('dataset.h5')
data = store['mydata']
store.close()

# Data in NumPy format
data = data.values

3

Este trabajo como un encanto ...

import csv
with open("data.csv", 'r') as f:
    data = list(csv.reader(f, delimiter=";"))

import numpy as np
data = np.array(data, dtype=np.float)

el código debe sangrarse correctamente dentro de su diseño de marcado de código.
surajs1n
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.