Jak odczytać dane CSV do tablicy rekordów w NumPy?

414

Zastanawiam się, czy istnieje bezpośredni sposób importować zawartość pliku CSV do rekordu tablicy, dużo w ten sposób, że grupę R read.table(), read.delim()oraz read.csv()import danych do rodziny ramki danych w R?

A może najlepszym sposobem jest użycie csv.reader (), a następnie zastosowanie czegoś takiego numpy.core.records.fromrecords()?

hatmatrix
źródło
Możliwy duplikat Jak czytać i zapisywać pliki CSV w Pythonie?
Martin Thoma,

Odpowiedzi:

645

Możesz użyć genfromtxt()do tego metody Numpy , ustawiając delimiterkwarg na przecinek.

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

Więcej informacji na temat funkcji można znaleźć w odpowiedniej dokumentacji .

Andrzej
źródło
10
Co jeśli chcesz czegoś innego? Jak ciągi i ints?
CGTheLegend
11
@CGTheLegend np.genfromtxt ('myfile.csv', delimiter = ',', dtype = None)
chickensoup
2
numpy.loadtxt również działało całkiem dobrze dla mnie
Yibo Yang
10
Próbowałem tego, ale dostaję tylko nanwartości, dlaczego? Dostaję także z loadtxt UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 155: ordinal not in range(128). Mam dane wejściowe takie jak ä i ö.
hhh
1
@ hhh spróbuj dodać encoding="utf8"argument. Python jest jednym z niewielu współczesnych elementów oprogramowania, które często powodują problemy z kodowaniem tekstu, które wydają się być przeszłością.
kolen
187

Poleciłbym read_csvfunkcję z pandasbiblioteki:

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

Daje to pandę DataFrame - pozwalającą na wiele przydatnych funkcji manipulacji danymi, które nie są bezpośrednio dostępne w przypadku tablic rekordów numpy .

DataFrame to dwuwymiarowa, oznaczona struktura danych z kolumnami potencjalnie różnych typów. Możesz myśleć o tym jak o arkuszu kalkulacyjnym lub tabeli SQL ...


Poleciłbym również genfromtxt. Ponieważ jednak pytanie dotyczy tablicy rekordów , w przeciwieństwie do tablicy normalnej, dtype=Noneparametr należy dodać do genfromtxtwywołania:

Biorąc pod uwagę plik wejściowy myfile.csv:

1.0, 2, 3
4, 5.5, 6

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

daje tablicę:

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

i

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

daje tablicę rekordów:

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

Ma to tę zaletę, że można łatwo zaimportować plik z wieloma typami danych (w tym ciągami znaków) .

atomh33ls
źródło
read_csv działa z przecinkami w cudzysłowie. Polecam ponad genfromtxt
Wietnam
3
użyj nagłówka = 0, aby pominąć pierwszy wiersz wartości, jeśli plik ma nagłówek 1-liniowy
c-chavez
Pamiętaj, że tworzy to tablicę 2d: np (1000, 1). np.genfromtxtnie robi tego: np (1000,).
Newskooler
74

Zmierzyłem czas

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

przeciw

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

na 4,6 miliona wierszy z około 70 kolumnami i stwierdził, że ścieżka NumPy zajęła 2 min 16 sekund, a metoda zrozumienia listy csv zajęła 13 sekund.

Poleciłbym metodę rozumienia listy csv, ponieważ najprawdopodobniej opiera się ona na wstępnie skompilowanych bibliotekach, a nie interpretera tak bardzo jak NumPy. Podejrzewam, że metoda pand miałaby podobny narzut tłumacza.

William komp
źródło
23
Testowałem podobny kod z plikiem csv zawierającym 2,6 miliona wierszy i 8 kolumn. numpy.recfromcsv () zajęło około 45 sekund, np.asarray (lista (csv.reader ())) zajęło około 7 sekund, a pandas.read_csv () zajęło około 2 sekund (!). (Plik został ostatnio odczytany z dysku we wszystkich przypadkach, więc znajdował się już w pamięci podręcznej plików systemu operacyjnego.) Myślę, że pójdę z pandami.
Matthias Fripp
5
Właśnie zauważyłem, że jest kilka uwag na temat projektu szybkiego parsera csv pand na stronie wesmckinney.com/blog/… . Autor dość poważnie podchodzi do wymagań dotyczących prędkości i pamięci. Możliwe jest również użycie as_recarray = True, aby uzyskać wynik bezpośrednio jako tablicę rekordów Pythona zamiast ramki danych pandy.
Matthias Fripp,
67

Możesz także spróbować recfromcsv()ustalić, które typy danych są w stanie zgadnąć, i zwrócić odpowiednio sformatowaną tablicę rekordów.

btel
źródło
9
Jeśli chcesz zachować nazwy zamówień / kolumn w CSV, możesz użyć następującego wywołania: numpy.recfromcsv(fname, delimiter=',', filling_values=numpy.nan, case_sensitive=True, deletechars='', replace_space=' ')Kluczowymi argumentami są trzy ostatnie.
eacousineau
16

Ponieważ próbowałem obu sposobów, używając NumPy i Pand, używanie pand ma wiele zalet:

  • Szybciej
  • Mniejsze zużycie procesora
  • 1/3 wykorzystania pamięci RAM w porównaniu do NumPy genfromtxt

To jest mój kod testowy:

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

Plik danych:

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

Z NumPy i pandami w wersjach:

$ pip freeze | egrep -i 'pandas|numpy'
numpy==1.13.3
pandas==0.20.2
HVNSweeting
źródło
5

Możesz użyć tego kodu, aby wysłać dane pliku CSV do tablicy:

import numpy as np
csv = np.genfromtxt('test.csv', delimiter=",")
print(csv)
chamzz.dot
źródło
4

Za pomocą numpy.loadtxt

Dość prosta metoda. Ale wymaga, aby wszystkie elementy były pływające (int i tak dalej)

import numpy as np 
data = np.loadtxt('c:\\1.csv',delimiter=',',skiprows=0)  
Xiaojian Chen
źródło
4

To najprostszy sposób:

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

Teraz każdy wpis w danych jest rekordem reprezentowanym jako tablica. Masz więc tablicę 2D. Oszczędzało mi to dużo czasu.

Matthew Park
źródło
Dlaczego powinniśmy mieć do czynienia z Pandami, skoro te narzędzia mają znacznie mniej wzdęć?
Christopher
3

Próbowałem tego:

import pandas as p
import numpy as n

closingValue = p.read_csv("<FILENAME>", usecols=[4], dtype=float)
print(closingValue)
muTheTechie
źródło
3

Sugerowałbym użycie tabel ( pip3 install tables). Możesz zapisać .csvplik za .h5pomocą pand ( pip3 install pandas),

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

Następnie możesz łatwo i przy mniejszym czasie, nawet w przypadku dużej ilości danych, załadować dane do tablicy NumPy .

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

# Data in NumPy format
data = data.values
Jatin Mandav
źródło
3

To działa jak urok ...

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)
Nihal Sargaiya
źródło
kod musi być odpowiednio wcięty w układzie znaczników kodu.
surajs1n