Wie lese ich CSV-Daten in ein Datensatzarray in NumPy?


413

Ich frage mich , ob es ein direkter Weg, um den Inhalt einer CSV - Datei in einen Rekord - Array, viel in der Art und Weise , dass R zu importieren read.table(), read.delim()und read.csv()Familie importiert Daten in R - Datenrahmen?

Oder ist es der beste Weg, csv.reader () zu verwenden und dann so etwas anzuwenden numpy.core.records.fromrecords()?


Antworten:


644

Sie können dazu die Numpy- genfromtxt()Methode verwenden, indem Sie das delimiterkwarg auf ein Komma setzen.

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

Weitere Informationen zur Funktion finden Sie in der jeweiligen Dokumentation .


10
Was ist, wenn Sie etwas von verschiedenen Arten wollen? Wie Strings und Ints?
CGTheLegend

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

2
numpy.loadtxt hat auch für mich ziemlich gut funktioniert
Yibo Yang

10
Ich habe es versucht, aber ich bekomme nur nanWerte, warum? Auch mit loadtxt bekomme ich UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 155: ordinal not in range(128). Ich habe Umlaute wie ä und ö in den Eingabedaten.
hhh

1
@hhh versuchen, encoding="utf8"Argument hinzuzufügen . Python ist eines der wenigen modernen Softwareteile, die häufig Probleme mit der Textcodierung verursachen, die sich wie Dinge aus der Vergangenheit anfühlen.
Kolen

187

Ich würde die read_csvFunktion aus der pandasBibliothek empfehlen :

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

Dies ergibt einen Pandas DataFrame , der viele nützliche Datenmanipulationsfunktionen ermöglicht, die mit Numpy-Record-Arrays nicht direkt verfügbar sind .

DataFrame ist eine zweidimensional beschriftete Datenstruktur mit Spalten potenziell unterschiedlicher Typen. Sie können sich das wie eine Tabelle oder eine SQL-Tabelle vorstellen ...


Ich würde es auch empfehlen genfromtxt. Da die Frage jedoch nach einem Datensatzarray im Gegensatz zu einem normalen Array fragt , muss der dtype=NoneParameter dem genfromtxtAufruf hinzugefügt werden :

Bei einer Eingabedatei myfile.csv:

1.0, 2, 3
4, 5.5, 6

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

gibt ein Array:

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

und

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

gibt ein Datensatzarray an:

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

Dies hat den Vorteil, dass Dateien mit mehreren Datentypen (einschließlich Zeichenfolgen) problemlos importiert werden können .


read_csv arbeitet mit Kommas in Anführungszeichen. Empfehlen Sie dies über genfromtxt
Viet

3
Verwenden Sie header = 0, um die erste Zeile in den Werten zu überspringen, wenn Ihre Datei einen 1-zeiligen Header hat
c-chavez

Beachten Sie, dass dadurch ein 2d-Array erstellt wird: z (1000, 1). np.genfromtxtmacht das nicht: zB (1000,).
Newskooler

74

Ich habe das zeitlich festgelegt

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

gegen

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

bei 4,6 Millionen Zeilen mit etwa 70 Spalten und stellte fest, dass der NumPy-Pfad 2 Minuten und 16 Sekunden und die Methode zum Verständnis der CSV-Liste 13 Sekunden dauerte.

Ich würde die CSV-Listen-Verständnismethode empfehlen, da sie höchstwahrscheinlich auf vorkompilierten Bibliotheken und nicht so sehr auf dem Interpreter wie NumPy basiert. Ich vermute, dass die Pandas-Methode einen ähnlichen Dolmetscheraufwand haben würde.


23
Ich habe ähnlichen Code mit einer CSV-Datei getestet, die 2,6 Millionen Zeilen und 8 Spalten enthält. numpy.recfromcsv () dauerte ungefähr 45 Sekunden, np.asarray (list (csv.reader ())) dauerte ungefähr 7 Sekunden und pandas.read_csv () dauerte ungefähr 2 Sekunden (!). (Die Datei wurde kürzlich in allen Fällen von der Festplatte gelesen, sodass sie sich bereits im Dateicache des Betriebssystems befand.) Ich denke, ich werde mit Pandas arbeiten.
Matthias Fripp

5
Ich habe gerade bemerkt, dass es unter wesmckinney.com/blog/… einige Hinweise zum Design des schnellen CSV-Parsers von Pandas gibt . Der Autor nimmt Geschwindigkeit und Speicherbedarf ziemlich ernst. Es ist auch möglich, as_recarray = True zu verwenden, um das Ergebnis direkt als Python-Datensatzarray und nicht als Pandas-Datenrahmen abzurufen.
Matthias Fripp

67

Sie können auch versuchen recfromcsv(), Datentypen zu erraten und ein ordnungsgemäß formatiertes Datensatzarray zurückzugeben.


9
Wenn Sie die Reihenfolge / Spaltennamen in der CSV beibehalten möchten, können Sie den folgenden Aufruf verwenden: numpy.recfromcsv(fname, delimiter=',', filling_values=numpy.nan, case_sensitive=True, deletechars='', replace_space=' ')Die Hauptargumente sind die letzten drei.
eacousineau

16

Da ich beide Möglichkeiten mit NumPy und Pandas ausprobiert habe, hat die Verwendung von Pandas viele Vorteile:

  • Schneller
  • Weniger CPU-Auslastung
  • 1/3 RAM-Nutzung im Vergleich zu NumPy genfromtxt

Dies ist mein Testcode:

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

Datendatei:

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

Mit NumPy und Pandas in Versionen:

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

5

Mit diesem Code können Sie CSV-Dateidaten an ein Array senden:

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

4

Verwenden von numpy.loadtxt

Eine ganz einfache Methode. Es erfordert jedoch, dass alle Elemente schweben (int und so weiter).

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

4

Dies ist der einfachste Weg:

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

Jetzt ist jeder Dateneintrag ein Datensatz, der als Array dargestellt wird. Sie haben also ein 2D-Array. Es hat mir so viel Zeit gespart.


Warum sollten wir uns mit Pandas herumschlagen müssen, wenn diese Tools so viel weniger Funktionen aufweisen?
Christopher

3

Ich habe es versucht:

import pandas as p
import numpy as n

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

3

Ich würde vorschlagen, Tabellen ( pip3 install tables) zu verwenden. Sie können Ihre .csvDatei .h5mit pandas ( pip3 install pandas) speichern.

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

Sie können Ihre Daten dann einfach und mit weniger Zeit auch für große Datenmengen in ein NumPy-Array laden .

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

# Data in NumPy format
data = data.values

3

Diese Arbeit als Zauber ...

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)

Code muss in seinem Code-Markdown-Layout richtig eingerückt sein.
surajs1n
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.