Como leio dados CSV em uma matriz de registros no NumPy?


414

Gostaria de saber se existe uma maneira direta para importar o conteúdo de um arquivo CSV em uma matriz disco, muito na maneira que de R read.table(), read.delim()e read.csv()as importações familiares de dados para quadro de dados do R?

Ou é a melhor maneira de usar csv.reader () e aplicar algo como numpy.core.records.fromrecords()?


Respostas:


646

Você pode usar o genfromtxt()método do Numpy para isso, definindo o delimiterkwarg como vírgula.

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

Mais informações sobre a função podem ser encontradas na respectiva documentação .


10
E se você quiser algo de tipos diferentes? Como strings e ints?
CGTheLegend

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

2
numpy.loadtxt funcionou muito bem para mim também
Yibo Yang

10
Eu tentei isso, mas só estou obtendo nanvalores, por quê? Também com loadtxt, estou recebendo UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 155: ordinal not in range(128). Eu tenho tremas como ä e ö nos dados de entrada.
hhh

1
@hhh tente adicionar encoding="utf8"argumento. O Python é uma das poucas peças de software modernas que freqüentemente causam problemas de codificação de texto, que parecem coisas do passado.
Kolen

187

Eu recomendaria a read_csvfunção da pandasbiblioteca:

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

Isso fornece um DataFrame do pandas - permitindo muitas funções úteis de manipulação de dados que não estão diretamente disponíveis com matrizes de registros numpy .

DataFrame é uma estrutura de dados rotulada bidimensional com colunas de tipos potencialmente diferentes. Você pode pensar nisso como uma planilha ou tabela SQL ...


Eu também recomendaria genfromtxt. No entanto, como a pergunta solicita uma matriz de registros , em oposição a uma matriz normal, o dtype=Noneparâmetro precisa ser adicionado à genfromtxtchamada:

Dado um arquivo de entrada, myfile.csv:

1.0, 2, 3
4, 5.5, 6

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

dá uma matriz:

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

e

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

fornece uma matriz de registros:

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

Isso tem a vantagem de que arquivos com vários tipos de dados (incluindo cadeias) podem ser facilmente importados .


O read_csv trabalha com vírgulas entre aspas. Recomendo este genfromtxt sobre
Viet

3
usar cabeçalho = 0 para ignorar a primeira linha nos valores, se o arquivo tem um cabeçalho 1-line
c-chavez

Lembre-se de que isso cria uma matriz 2D: por exemplo (1000, 1). np.genfromtxtnão faz isso: por exemplo (1000,).
Newskooler

74

Eu cronometrei o

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>)

em 4,6 milhões de linhas com cerca de 70 colunas e constatou que o caminho do NumPy levou 2 minutos e 16 segundos e o método de compreensão da lista csv levou 13 segundos.

Eu recomendaria o método de compreensão da lista csv, pois ele provavelmente depende de bibliotecas pré-compiladas e não do intérprete tanto quanto do NumPy. Eu suspeito que o método dos pandas teria uma sobrecarga de intérprete semelhante.


23
Testei código semelhante a este com um arquivo csv contendo 2,6 milhões de linhas e 8 colunas. numpy.recfromcsv () demorou cerca de 45 segundos, np.asarray (list (csv.reader ())) demorou cerca de 7 segundos e pandas.read_csv () demorou cerca de 2 segundos (!). (O arquivo foi lido recentemente do disco em todos os casos, portanto já estava no cache de arquivos do sistema operacional.) Acho que vou com os pandas.
Matthias Fripp

5
Acabei de notar que há algumas notas sobre o design do analisador csv rápido do pandas em wesmckinney.com/blog/… . O autor leva muito a sério os requisitos de velocidade e memória. Também é possível usar as_recarray = True para obter o resultado diretamente como uma matriz de registros Python, em vez de um dataframe do pandas.
Matthias Fripp

67

Você também pode tentar recfromcsv()adivinhar os tipos de dados e retornar uma matriz de registros formatada corretamente.


9
Se você deseja manter os nomes dos pedidos / colunas no CSV, pode usar a seguinte chamada: numpy.recfromcsv(fname, delimiter=',', filling_values=numpy.nan, case_sensitive=True, deletechars='', replace_space=' ')Os principais argumentos são os três últimos.
eacousineau

16

Como tentei nos dois sentidos usando o NumPy e o Pandas, o uso de pandas tem muitas vantagens:

  • Mais rápido
  • Menos uso da CPU
  • Uso de 1/3 de RAM em comparação com o NumPy genfromtxt

Este é o meu código de teste:

$ 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')

Arquivo de dados:

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

Com NumPy e pandas nas versões:

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

5

Você pode usar esse código para enviar dados do arquivo CSV para uma matriz:

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

4

Usando numpy.loadtxt

Um método bastante simples. Mas exige que todos os elementos sejam flutuados (int e assim por diante)

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

4

Esta é a maneira mais fácil:

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

Agora, cada entrada nos dados é um registro, representado como uma matriz. Então você tem uma matriz 2D. Isso me salvou muito tempo.


Por que deveríamos ter que mexer com o Pandas, quando essas ferramentas têm muito menos recursos inchados?
Christopher

3

Eu tentei isso:

import pandas as p
import numpy as n

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

3

Eu sugeriria o uso de tables ( pip3 install tables). Você pode salvar seu .csvarquivo .h5usando pandas ( pip3 install pandas),

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

Você pode facilmente, e com menos tempo, mesmo para uma enorme quantidade de dados, carregar seus dados em uma matriz NumPy .

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

# Data in NumPy format
data = data.values

3

Este trabalho como um 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)

o código precisa ser recuado adequadamente dentro de seu layout de marcação de código.
precisa saber é o seguinte
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.