2016-08-08 23 views
0

Nehmen wir an, ich habe ein Byte-Objekt, das einige Daten darstellt, und ich möchte es in eine numpy Array über np.genfromtxt konvertieren. Ich habe Probleme zu verstehen, wie ich in diesem Fall mit Strings umgehen soll. Beginnen wir mit dem Folgenden:Verständnis NumPy Interpretation von Zeichenfolge Datentypen

from io import BytesIO 
import numpy as np 

text = b'test, 5, 1.2' 
types = ['str', 'i4', 'f4'] 
np.genfromtxt(BytesIO(text), delimiter = ',', dtype = types) 

Dies funktioniert nicht. Es wirft

TypeError: data type not understood

Wenn ich types so ändern, dass types = ['c', 'i4', 'f4']

Dann wird der numpy Aufruf gibt

array((b't', 5, 1.2000000476837158), 
     dtype=[('f0', 'S1'), ('f1', '<i4'), ('f2', '<f4')]) 

So funktioniert es, aber ich bin nur den ersten Buchstaben der Zeichenfolge bekommen, offensichtlich.

Wenn ich c8 oder c16 für die dtype von test, dann bekomme ich

array(((nan+0j), 5, 1.2000000476837158), 
     dtype=[('f0', '<c8'), ('f1', '<i4'), ('f2', '<f4')]) 

den Müll ist. Ich habe auch versucht, a und U, keinen Erfolg. Wie in der Welt bekomme ich genfromtxt, um Elemente als String zu erkennen und zu speichern?


Edit: Ich nehme Teil des USGABE ist, dass dies ein Objekt bytes ist. Allerdings, wenn ich stattdessen eine normale Zeichenfolge als text verwenden, und verwenden Sie StringIO statt BytesIO, dann wirft genfromtxt einen Fehler:

TypeError: Can't convert Bytes object to str implicitly

+0

Haben geben Sie eine Länge mit 'a' – user2357112

+0

@ user2357112 No ... Danke ... die Lösung ist immer zu einfach – Anonymous

Antwort

0

In meiner Python3 Sitzung:

In [568]: text = b'test, 5, 1.2' 
# I don't need BytesIO since genfromtxt works with a list of 
# byte strings, as from text.splitlines() 

In [570]: np.genfromtxt([text], delimiter=',', dtype=None) 
Out[570]: 
array((b'test', 5, 1.2), 
     dtype=[('f0', 'S4'), ('f1', '<i4'), ('f2', '<f8')]) 

Wenn links zu seinen eigenen Geräten genfromtxt folgert, dass das 1. Feld S4 - 4 Bytestring Zeichen sein sollte.

Ich könnte auch mit den Typen explizit sein:

In [571]: types=['S4', 'i4', 'f4'] 
In [572]: np.genfromtxt([text],delimiter=',',dtype=types) 
Out[572]: 
array((b'test', 5, 1.2000000476837158), 
     dtype=[('f0', 'S4'), ('f1', '<i4'), ('f2', '<f4')]) 
In [573]: types=['S10', 'i', 'f'] 
In [574]: np.genfromtxt([text],delimiter=',',dtype=types) 
Out[574]: 
array((b'test', 5, 1.2000000476837158), 
     dtype=[('f0', 'S10'), ('f1', '<i4'), ('f2', '<f4')]) 

In [575]: types=['U10', 'int', 'float'] 
In [576]: np.genfromtxt([text],delimiter=',',dtype=types) 
Out[576]: 
array(('test', 5, 1.2), 
     dtype=[('f0', '<U10'), ('f1', '<i4'), ('f2', '<f8')]) 

ich entweder S oder U (Unicode) angeben können, aber ich muss auch die Länge angeben. Ich glaube nicht, dass es einen Weg mit genfromtxt gibt, um die Länge abzuleiten - außer für den None Typ. Ich müsste mich in den Code vertiefen, um zu sehen, wie er die Stringlänge ableitet.

Ich kann auch dieses Array mit np.array erstellen (durch ein Tupel von Teil machen, und eine korrekte dtype geben:

In [599]: np.array(tuple(text.split(b',')), dtype=[('f0', 'S4'), ('f1', '<i4'), ('f2', '<f8')]) 
Out[599]: 
array((b'test', 5, 1.2), 
     dtype=[('f0', 'S4'), ('f1', '<i4'), ('f2', '<f8')])