2013-10-18 8 views
12

Als Teil eines breiteren Programms, an dem ich gerade arbeite, endete ich mit Objektarrays mit Strings, 3D Koordinaten und so weiter gemischt. Ich weiß, dass Objektarrays im Vergleich zu strukturierten Arrays nicht besonders beliebt sind, aber ich hoffe, dass ich das umgehen kann, ohne viele Codes zu ändern.Wie man ein Numpy 2D Array mit Objekt dtype in ein normales 2D Array von Floats konvertiert

Lässt jede Zeile meiner Array obj_array übernehmen (mit N Zeilen) hat Format

Single entry/object of obj_array: ['NAME',[10.0,20.0,30.0],....] 

Jetzt versuche ich, dieses Objekt Array zu laden und in Scheiben schneiden die 3D-Chunk koordinieren. Bis hierhin läuft alles gut mit der einfachen Frage lässt sich sagen für.

obj_array[:,[1,2,3]] 

jedoch das Ergebnis auch Array ein Objekt ist, und ich werde Problem konfrontiert, wie ich mit einem 2D-Array von Schwimmern bilden will:

size [N,3] of N rows and 3 entries of X,Y,Z coordinates 

Vorerst ich über Zeilen bin Looping und jede Zuordnung Zeile zu einer Zeile eines Ziel-2D-Flot-Arrays, um das Problem zu umgehen. Ich frage mich, ob es einen besseren Weg mit Array-Konvertierungstools von numpy gibt? Ich habe ein paar Dinge ausprobiert und konnte es nicht umgehen.

Centers = np.zeros([N,3]) 

for row in range(obj_array.shape[0]): 
    Centers[row,:] = obj_array[row,1] 

Dank

+0

Können Sie einen einfachen Beispielcode zeigen - wie die Originaldaten aussehen und wie Ihr Conversion-Code aussieht? Es wird es für Sie einfacher machen, Sie angemessen zu beraten. – Floris

Antwort

8

Nasty kleines Problem ... Ich habe um mit diesem Spielzeug Beispiel wurde täuscht:

>>> arr = np.array([['one', [1, 2, 3]],['two', [4, 5, 6]]], dtype=np.object) 
>>> arr 
array([['one', [1, 2, 3]], 
     ['two', [4, 5, 6]]], dtype=object) 

Meine erste Vermutung war:

>>> np.array(arr[:, 1]) 
array([[1, 2, 3], [4, 5, 6]], dtype=object) 

Aber das hält die object dtype, also vielleicht dann:

>>> np.array(arr[:, 1], dtype=np.float) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: setting an array element with a sequence. 

Sie können normalerweise dieses Problem umgehen die folgenden Aktionen ausführen:

>>> np.array(arr[:, 1], dtype=[('', np.float)]*3).view(np.float).reshape(-1, 3) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: expected a readable buffer object 

Nicht hier aber die rätselhafte Art war. Offenbar ist es die Tatsache, dass die Objekte in Ihrem Array-Listen sind, dass dies abwirft, als die Listen mit Tupeln ersetzen funktioniert:

>>> np.array([tuple(j) for j in arr[:, 1]], 
...   dtype=[('', np.float)]*3).view(np.float).reshape(-1, 3) 
array([[ 1., 2., 3.], 
     [ 4., 5., 6.]]) 

Da es keine völlig zufriedenstellende Lösung zu sein scheint, ist die einfachste ist wahrscheinlich gehen mit:

>>> np.array(list(arr[:, 1]), dtype=np.float) 
array([[ 1., 2., 3.], 
     [ 4., 5., 6.]]) 

Obwohl das wird nicht sehr effizient sein, wahrscheinlich besser mit etwas zu gehen wie:

>>> np.fromiter((tuple(j) for j in arr[:, 1]), dtype=[('', np.float)]*3, 
...    count=len(arr)).view(np.float).reshape(-1, 3) 
array([[ 1., 2., 3.], 
     [ 4., 5., 6.]]) 
1

Sie möchten können strukturierte arr verwenden Wenn Sie auf die Namen und die Werte unabhängig zugreifen müssen, können Sie dies leicht tun.In diesem Beispiel gibt es zwei Datenpunkte:

x = zeros(2, dtype=[('name','S10'), ('value','f4',(3,))]) 
x[0][0]='item1' 
x[1][0]='item2' 
y1=x['name'] 
y2=x['value'] 

das Ergebnis:

>>> y1 
array(['item1', 'item2'], 
     dtype='|S10') 
>>> y2 
array([[ 0., 0., 0.], 
     [ 0., 0., 0.]], dtype=float32) 

Weitere Details: http://docs.scipy.org/doc/numpy/user/basics.rec.html

3

Basierend auf Jaimes Spielzeug Beispiel denke ich, Sie dies einfach sehr tun können, mit np.vstack():

arr = np.array([['one', [1, 2, 3]],['two', [4, 5, 6]]], dtype=np.object) 
float_arr = np.vstack(arr[:, 1]).astype(np.float) 

Dies wird w ork unabhängig davon, ob die 'numerischen' Elemente in Ihrem Objekt-Array 1D numpy Arrays, Listen oder Tupel sind.

1

Dies funktioniert gut arbeiten auf Ihrem Array Arr, um von einem Objekt in ein Array von Schwimmern zu konvertieren. Die Verarbeitung der Zahlen ist extrem einfach. Danke für diesen letzten Beitrag !!!! Ich änderte es nur um jede Datenrahmen Größe zu umfassen:

float_arr = np.vstack(arr[:, :]).astype(np.float) 
+0

Dies ist mehr ein Kommentar als eine Antwort. Bezieht es sich auf die Antwort von ali_m? – jogo

0

Das ist viel schneller, nur das Objekt Array in einen float-Array NumPy zu konvertieren: arr=np.array(arr, dtype=[('O', np.float)]).astype(np.float) - von dort ohne Looping, Index mag es nur, dass Sie normalerweise tun auf einem NumPy-Array. Sie müssten es jedoch in Chunks mit Ihren verschiedenen Datentypen arr[:, 1], arr[:,2], usw. tun. Hatte das gleiche Problem mit einem NumPy-Tuple-Objekt von einer C++ DLL-Funktion zurückgegeben - Konvertierung für 17M Elemente dauert < 2s.

+0

Wenn jemand diese Lösung oben tatsächlich versuchte und es profilierte, würde es nicht downvoted werden. – Matt

0

Dieses Problem tritt normalerweise auf, wenn Sie ein Dataset mit verschiedenen Typen haben, normalerweise Daten in der ersten Spalte oder so.

Was ich zu tun habe, ist die Datumsspalte in einer anderen Variablen zu speichern; und nimm den Rest der "X-Matrix von Features" in X. Also habe ich zum Beispiel Daten und X.

Dann wende ich die Umstellung auf die X-Matrix als:

X = np.array(list(X[:,:]), dtype=np.float)

Hoffnung zu helfen!