2015-10-07 4 views
8

Ich habe eine CSV-Datei, die ich von der WHO-Website heruntergeladen (http://apps.who.int/gho/data/view.main.52160, Downloads, "Mehrzweck-Tabelle im CSV-Format"). Ich versuche, die Datei in ein numpy Array zu laden. Hier ist mein Code:Lade UTF-8-Datei in Python 3 mit numpy.genfromtxt

import numpy 
#U75 - unicode string of max. length 75 
world_alcohol = numpy.genfromtxt("xmart.csv", dtype="U75", skip_header=2, delimiter=",") 
print(world_alcohol) 

Und ich

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 2: ordinal not in range(128).

Ich denke, dass numpy ein Problem hat die Zeichenfolge "Côte d'Ivoire" zu lesen. Die Datei ist richtig codiert UTF-8 (nach meinem Texteditor). Ich benutze Python 3.4.3 und numpy 1.9.2.

Was mache ich falsch? Wie kann ich die Datei in numpy lesen?

Antwort

8

In Python3 kann ich tun:

In [224]: txt = "Côte d'Ivoire" 
In [225]: x = np.zeros((2,),dtype='U20') 
In [226]: x[0] = txt 
In [227]: x 
Out[227]: 
array(["Côte d'Ivoire", ''], dtype='<U20') 

Was ich wahrscheinlich bedeutet Datei ein ‚UTF-8‘ öffnen konnte (regelmäßige, nicht-Byte-Modus) und Leseleitungen, und ordnen sie Elemente eines Arrays wie x.

Aber genfromtxt besteht darauf, mit Byte-Strings (ascii) zu arbeiten, die nicht mit dem größeren UTF-8 Satz (7 Bytes v 8) umgehen können. Also muss ich decode irgendwann anwenden, um ein U Array zu erhalten.

Ich kann es in ein Array 'S' laden mit genfromtxt:

In [258]: txt="Côte d'Ivoire" 
In [259]: a=np.genfromtxt([txt.encode()],delimiter=',',dtype='S20') 
In [260]: a 
Out[260]: 
array(b"C\xc3\xb4te d'Ivoire", dtype='|S20') 

und gelten decode auf einzelne Elemente:

In [261]: print(a.item().decode()) 
Côte d'Ivoire 

In [325]: print _ 
Côte d'Ivoire 

Oder np.char.decode nutzen es aus einer Anordnung an jedes Element anzuwenden :

In [263]: np.char.decode(a) 
Out[263]: 
array("Côte d'Ivoire", dtype='<U13') 
In [264]: print(_) 
Côte d'Ivoire 

genfromtxt lassen me s angeben converters:

In [297]: np.genfromtxt([txt.encode()],delimiter=',',dtype='U20', 
    converters={0:lambda x: x.decode()}) 
Out[297]: 
array("Côte d'Ivoire", dtype='<U20') 

Wenn die csv eine Mischung aus Strings und Zahlen hat, dieser converters Ansatz leichter sein wird als die np.char.decode zu verwenden. Geben Sie den Konverter für jede String-Spalte an.

(Siehe meine früheren Bearbeitungen für Python2 versucht).

+0

Nicht OP, aber danke für den klaren und nützlichen Aufbau der Antwort. – KobeJohn

+1

Vielen Dank für die Antwort. Es klappt! Ich fange gerade mit Python an und finde es komisch, dass numpy UTF-8 nicht sofort auslesen kann. Ich habe gelesen, dass Python leicht zu bedienen ist und einfach zu bedienen ist, aber das Lesen von UTF-8 erfordert zusätzliche Konvertierungen? Ich dachte, wir leben im Jahr 2015. – JustAC0der