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.